2010-08-08 8 views
41
class Example(object): 
    def the_example(self): 
     itsProblem = "problem" 

theExample = Example() 
print(theExample.itsProblem) 

¿Cómo accedo a la variable de una clase? He intentado agregar esta definición:¿Accediendo a las variables de miembro de una clase en Python?

def return_itsProblem(self): 
    return itsProblem 

Sin embargo, eso también falla.

+0

título editado, pregunta en realidad acerca de las variables de clase "estáticos": http://stackoverflow.com/questions/707380/in-python-how-can-i-access- static-class-variables-within-class-methods –

Respuesta

80

La respuesta, en pocas palabras

En su ejemplo, itsProblem es una variable local.

Debe usar self para establecer y obtener variables de instancia. Puede configurarlo en el método __init__. A continuación, el código sería:

class Example(object): 
    def __init__(self): 
     self.itsProblem = "problem" 


theExample = Example() 
print(theExample.itsProblem) 

Pero si quieres una verdadera variable de clase, a continuación, utilizar el nombre de clase directamente:

class Example(object): 
    itsProblem = "problem" 


theExample = Example() 
print(theExample.itsProblem) 
print (Example.itsProblem) 

Pero tenga cuidado con esto, ya que theExample.itsProblem se ajusta automáticamente para que sea igual a Example.itsProblem, pero no es la misma variable y puede cambiarse independientemente.

Algunas explicaciones

En Python, las variables coche pueden crear de forma dinámica. Para ello, puede hacer lo siguiente:

class Example(object): 
    pass 

Example.itsProblem = "problem" 

e = Example() 
e.itsSecondProblem = "problem" 

print Example.itsProblem == e.itsSecondProblem 

imprime

verdaderos

Por lo tanto, eso es exactamente lo que haces con los ejemplos anteriores.

De hecho, en Python usamos self como this, pero es un poco más que eso. Self es el primer argumento para cualquier método de objeto porque el primer argumento es siempre la referencia del objeto. Esto es automático, ya sea que lo llame o no.

Lo que significa que puede hacer:

class Example(object): 
    def __init__(self): 
     self.itsProblem = "problem" 


theExample = Example() 
print(theExample.itsProblem) 

O:

class Example(object): 
    def __init__(my_super_self): 
     my_super_self.itsProblem = "problem" 


theExample = Example() 
print(theExample.itsProblem) 

Es exactamente lo mismo. El primer argumento de CUALQUIER método de objeto es el objeto actual, solo lo llamamos self como una convención. Y agrega solo una variable a este objeto, de la misma manera que lo haría desde afuera.

Ahora, sobre las variables de clase.

Al hacer:

class Example(object): 
    itsProblem = "problem" 


theExample = Example() 
print(theExample.itsProblem) 

Se dará cuenta de que primero establecemos una clase variable de, a continuación, accedemos un objeto (instancia) Variable. Nunca establecemos esta variable de objeto pero funciona, ¿cómo es posible?

Bueno, Python intenta obtener primero la variable de objeto, pero si no puede encontrarla, le dará la variable de clase. Advertencia: la variable de clase se comparte entre instancias y la variable de objeto no.

Como conclusión, nunca utilice variables de clase para establecer los valores predeterminados de las variables del objeto. Use __init__ para eso.

Eventualmente, aprenderá que las clases de Python son instancias y, por lo tanto, objetos en sí mismos, lo que brinda una nueva comprensión para comprender lo anterior. Vuelve y vuelve a leer esto más tarde, una vez que te des cuenta de eso.

+0

+1 por __init__. Para eso es para eso. – Abizern

+0

dices: "theExample.itsProblem se configura automáticamente para ser igual a Example.itsProblem, pero no es la misma variable y se puede cambiar de forma independiente", pero eso no es del todo correcto y tu frase es engañosa. Confío en que sepas qué está pasando allí, así que sugiero reformularlo: "es la misma variable, pero se puede reenviar de forma independiente para cada objeto". – jsbueno

+0

Sí, pero el enlace es un concepto que alguien utiliza para otro lenguaje de programación como Java o C (como sospecho que es el OP) que es completamente desconocido. Luego, quisiera explicar qué es el enlace, luego el enlace tardío, luego el problema con las referencias sobre los objetos mutables. Sería demasiado largo. Creo que a veces debes sacrificar la precisión en el altar de la comprensión. –

8

Está declarando una variable local, no una variable de clase. Para establecer una variable de instancia (atributo), utilice

class Example(object): 
    def the_example(self): 
     self.itsProblem = "problem" # <-- remember the 'self.' 

theExample = Example() 
theExample.the_example() 
print(theExample.itsProblem) 

Para establecer un (miembro también conocido como estática) class variable, utilice

class Example(object): 
    def the_example(self): 
     Example.itsProblem = "problem" 
     # or, type(self).itsProblem = "problem" 
     # depending what you want to do when the class is derived. 
+0

Excepto que las variables de clase se declaran * una vez * a * nivel de clase *. Tu camino lo reiniciará en cada instanciación, esto realmente no es lo que quieres. También vea http://stackoverflow.com/questions/2709821/python-self-explained para la lógica detrás del self explícito. – delnan

0

Si usted tiene una función de instancia (es decir, uno que se pasa uno mismo), puede utilizar uno mismo para obtener una referencia a la clase utilizando self.__ __class__ __

Por ejemplo, en el código de abajo tornado crea una instancia para manejar las peticiones GET, pero podemos obtener la clase get_handler y usarla para contener un cliente riak, por lo que no es necesario crear uno para cada solicitud.

import tornado.web 
import riak 

class get_handler(tornado.web.requestHandler): 
    riak_client = None 

def post(self): 
    cls = self.__class__ 
    if cls.riak_client is None: 
     cls.riak_client = riak.RiakClient(pb_port=8087, protocol='pbc') 
    # Additional code to send response to the request ... 
0

Implemente la declaración de devolución como en el ejemplo a continuación. Deberías ser bueno. Espero que ayude a alguien ...

class Example(object): 
     def the_example(self): 
     itsProblem = "problem" 
     return itsProblem 

    theExample = Example() 
    print theExample.the_example() 
+0

Debería corregir la sangría de su código. También hay respuestas superiores a esta pregunta y tu respuesta es una variación básica de esas respuestas, no una solución alternativa ... –

Cuestiones relacionadas