objects learn functions classes and python class scope static-binding

learn - python class methods



¿Por qué el enlace estático funciona de manera diferente para la clase y la función? (1)

Sí, parece que la documentación es bastante engañosa. Una definición de clase en realidad no funciona del mismo modo que otros bloques normales:

global_one = 0 class A(object): x = global_one + 10 global_one = 100 y = global_one + 20 del global_one z = global_one + 30 a = A() print a.x, a.y, a.z, global_one

resultados en: 10, 120, 30, 0

Si prueba lo mismo con una función, obtiene un UnboundLocalError en su primer acceso a global_one .

La razón para esto es que las definiciones de clases como normales tienen acceso al alcance principal, sin embargo, todas las asignaciones de nombres NO modifican un ámbito local, pero de hecho se capturan en el diccionario de atributos de datos de la clase. Hay indicaciones sobre esto en la documentación, pero ciertamente no es obvio.

En python (probado en 2.7.6), todas las variables están vinculadas estáticamente a un ámbito en tiempo de compilación. Este proceso está bien descrito en http://www.python.org/dev/peps/pep-0227/ y http://docs.python.org/2.7/reference/executionmodel.html

Se establece explícitamente que "si se produce una operación de vinculación de nombre en cualquier lugar dentro de un bloque de código, todos los usos del nombre dentro del bloque se tratan como referencias al bloque actual".

Una función es un bloque de código, por lo que el siguiente código falla porque x se asigna después de su uso (por lo que en tiempo de compilación se define local porque está asignado en alguna parte de la función, pero en tiempo de ejecución se usa antes de vincularse).

x = 1 def f(): print x x = 2 print x >>> f() Traceback (most recent call last): File "<pyshell#46>", line 1, in <module> f() File "<pyshell#45>", line 2, in f print x UnboundLocalError: local variable ''x'' referenced before assignment

Una clase también es un bloque de código, por lo que debemos observar exactamente el mismo comportamiento. Pero esto no es lo que observo. Mira este ejemplo:

x = 1 class C(): y = x + 10 x = 2 def __init__(self): print C.y >>> C.x 2 >>> C.y 11 >>> C() 11 <__main__.C instance at 0x00000000027CC9C8>

Como la definición de clase es un bloque de código, cualquier asignación dentro de este bloque debe hacer que la variable sea local. Entonces x debe ser local para la clase C , por lo que y = x + 10 debería dar como resultado un UnboundLocalError . ¿Por qué no hay tal error?