Propósito de llamar a la función sin paréntesis python

Considera lo siguiente:

class objectTest(): def __init__(self,a): self.value = a def get_value(self): return self.value class execute(): def __init__(self): a = objectTest(1) b = objectTest(1) print(a == b) print(a.get_value() == b.get_value) print(a.get_value() == b.get_value()) print(a.get_value == b.get_value) if __name__ == '__main__': execute = execute(); 

Este código de retorno

 >>> False False True False 

Dado que get_value es una función, esperaría que la ejecución se detenga y devuelva un error, pero no lo hace. ¿Alguien puede explicar por qué el intérprete de Python permite este tipo de syntax en lugar de generar un error de atributo, lo que en mi caso me habría ahorrado un tiempo precioso?

Related of "Propósito de llamar a la función sin paréntesis python"

Como se mencionó, las funciones y los métodos son objetos de primera clase. Los llamas lanzando algunos paréntesis (paréntesis) al final. Pero parece que quieres más motivación por qué Python incluso nos permite hacer eso. ¿Por qué nos debe importar si las funciones son de primera clase o no?

A veces, no quiere llamarlos, quiere pasar una referencia a la propia llamada.

 from multiprocessing import Process t = Process(target=my_long_running_function) 

Si my_long_running_function corchetes después de lo anterior, ejecuta tu función my_long_running_function en tu hilo principal; Apenas lo que querías! Quería darle a Process una referencia a su llamable que se ejecutará en un nuevo proceso.

A veces solo quieres especificar el que se puede llamar y dejar algo más …

 def do_something(s): return s[::-1].upper() map(do_something,['hey','what up','yo']) Out[3]: ['YEH', 'PU TAHW', 'OY'] 

( map en este caso) rellene sus argumentos.

Tal vez solo quieras colocar un montón de callables en alguna colección y obtener el que quieras de una manera dinámica.

 from operator import * str_ops = {'<':lt,'>':gt,'==':eq} # etc op = str_ops.get(my_operator) if op: result = op(lhs,rhs) 

Lo anterior es una forma de asignar representaciones de cadenas de operadores a su acción real.

Las funciones y los métodos en Python también son objetos en sí mismos. Por lo tanto, puedes compararlos como lo harías con cualquier otro objeto.

 >>> type(a.get_value)  >>> type(a.get_value())  

Normalmente, por supuesto, no se comparan los métodos entre sí o cualquier otra cosa, porque no es muy útil. Un lugar en el que es útil es cuando se quiere pasar una función a otra función.

 print(a.get_value() == b.get_value) # 1 print(a.get_value() == b.get_value()) # 2 print(a.get_value == b.get_value) # 3 

1) ¿Es el valor de retorno de la llamada a.get_value () igual al método b.get_value?

2) ¿A.get_value () devuelve lo mismo que b.get_value ()?

3) ¿Es el método-referencia a.get_value igual al método-referencia b.get_value?

Esto es perfectamente válido Python 🙂

 def mul(a, b): return a * b def add(a, b): return a + b def do(op, a, b): return op(a, b) do(add, 2, 3) # return 5 

Varios comentaristas quieren un ejemplo de dónde esto es útil. Una aplicación está en enhebrar. Necesitamos pasar el objective al hilo sin usar corchetes. De lo contrario, el objective se crea en el hilo principal, que es lo que estamos tratando de evitar.

Ejemplo:

En test1.py yo llamo a ThreadTest sin usar corchetes. test_thread comienza en el hilo y permite que test1.py continúe ejecutándose.

En test2.py, paso ThreadTest () como objective. En este caso, el hilo no permite que test2.py continúe ejecutándose.

test1.py

 import threading from thread_test import ThreadTest thread = threading.Thread(target=ThreadTest) thread.start() print('not blocked') 

test2.py

 import threading from thread_test import ThreadTest thread = threading.Thread(target=ThreadTest()) thread.start() print('not blocked') 

test_thread.py

 from time import sleep class ThreadTest(): def __init__(self): print('thread_test started') while True: sleep(1) print('test_thread') 

salida de test1.py:

 thread_test started not blocked test_thread test_thread test_thread 

salida de test2.py:

 thread_test started test_thread test_thread test_thread 

Estoy usando python3.5 en Linux Mint.