En Python, ¿cómo puedo acceder a las variables de clase “estáticas” dentro de los métodos de clase?

Si tengo el siguiente código python:

class Foo(object): bar = 1 def bah(self): print(bar) f = Foo() f.bah() 

Se queja

 NameError: global name 'bar' is not defined 

¿Cómo puedo acceder a la bar variable de clase / estática dentro del método bah ?

En lugar de la bar usa self.bar o Foo.bar . Asignar a Foo.bar creará una variable estática, y asignarlo a self.bar creará una variable de instancia.

Definir el método de clase:

 class Foo(object): bar = 1 @classmethod def bah(cls): print cls.bar 

Ahora, si bah() tiene que ser un método de instancia (es decir, tener acceso a sí mismo), todavía puede acceder directamente a la variable de clase.

 class Foo(object): bar = 1 def bah(self): print self.bar 

Como con todos los buenos ejemplos, ha simplificado lo que realmente está tratando de hacer. Esto es bueno, pero vale la pena señalar que Python tiene mucha flexibilidad cuando se trata de variables de clase en comparación con las de instancia. Lo mismo se puede decir de los métodos. Para una buena lista de posibilidades, recomiendo leer la introducción de las clases de nuevo estilo de Michael Fötsch , especialmente las secciones 2 a 6.

Una cosa que requiere mucho trabajo para recordar al comenzar es que Python no es Java. Más que un cliché. En java, se comstack una clase completa, lo que hace que la resolución del espacio de nombres sea realmente simple: cualquier variable declarada fuera de un método (en cualquier lugar) es una instancia (o, si es estática, una clase) y está implícitamente accesible dentro de los métodos.

Con Python, la gran regla de oro es que hay tres espacios de nombres que se buscan, en orden, para las variables:

  1. La función / método
  2. El modulo actual
  3. Builtins

{begin pedagogy}

Hay excepciones limitadas a esto. El principal que se me ocurre es que, cuando se carga una definición de clase, la definición de clase es su propio espacio de nombres implícito. Pero esto dura solo mientras se carga el módulo, y se omite por completo cuando se está dentro de un método. Así:

 >>> class A(object): foo = 'foo' bar = foo >>> A.foo 'foo' >>> A.bar 'foo' 

pero:

 >>> class B(object): foo = 'foo' def get_foo(): return foo bar = get_foo() Traceback (most recent call last): File "", line 1, in  class B(object): File "", line 5, in B bar = get_foo() File "", line 4, in get_foo return foo NameError: global name 'foo' is not defined 

{end pedagogy}

Al final, lo que hay que recordar es que tiene acceso a cualquiera de las variables a las que desea acceder, pero probablemente no implícitamente. Si tus metas son simples y directas, entonces ir por Foo.bar o self.bar probablemente será suficiente. Si su ejemplo se está volviendo más complicado, o si desea hacer cosas extravagantes como la herencia (¡puede heredar métodos estáticos / de clase!), O la idea de referirse al nombre de su clase dentro de la misma clase le parece errónea, consulte La intro me vinculo.

 class Foo(object): bar = 1 def bah(self): print Foo.bar f = Foo() f.bah() 
 class Foo(object) : bar = 1 def bah(object_reference) : object_reference.var=Foo.bar return object_reference.var f = Foo() print 'var=', f.bah()