Si tengo el siguiente código de 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 clase / variable estática bar
dentro del método bah
?
python
oop
static-variables
Ross Rogers
fuente
fuente
Respuestas:
En lugar de
bar
usarself.bar
oFoo.bar
. Asignar aFoo.bar
creará una variable estática y asignar aself.bar
creará una variable de instancia.fuente
Definir método de clase:
Ahora, si
bah()
tiene que ser un método de instancia (es decir, tener acceso a uno mismo), aún puede acceder directamente a la variable de clase.fuente
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 versus instancia. Lo mismo puede decirse de los métodos. Para obtener una buena lista de posibilidades, recomiendo leer la introducción de las clases de estilo nuevo 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 simple cliché. En java, se compila 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) son variables de instancia (o, si es estática, de clase) y son accesibles implícitamente dentro de los métodos.
Con python, la gran regla general es que hay tres espacios de nombres que se buscan, en orden, para las variables:
{begin pedagogy}
Hay excepciones limitadas a esto. Lo 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 encuentra dentro de un método. Así:
pero:
{end pedagogy}
Al final, lo que hay que recordar es que usted no tiene acceso a ninguna de las variables que desea tener acceso, pero probablemente no de forma implícita. Si sus objetivos son simples y directos, entonces elegir Foo.bar o self.bar probablemente será suficiente. Si su ejemplo se está volviendo más complicado, o si desea hacer cosas elegantes como la herencia (¡puede heredar métodos estáticos / de clase!), O la idea de referirse al nombre de su clase dentro de la clase en sí misma le parece incorrecta, consulte La introducción que he vinculado.
fuente
fuente
fuente