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

theExample = Example() 
print(theExample.itsProblem) 

Come accedere alla variabile di una classe? Ho provato ad aggiungere questa definizione:Accesso alle variabili membro di una classe in Python?

def return_itsProblem(self): 
    return itsProblem 

Eppure, che non riesce anche.

+0

titolo modificato, domanda in realtà circa classe variabili "statiche": http://stackoverflow.com/questions/707380/in-python-how-can-i-access- static-class-variables-within-class-methods –

risposta

80

La risposta, in poche parole

Nella tua esempio, itsProblem è una variabile locale.

È necessario utilizzare self per impostare e ottenere variabili di istanza. È possibile impostarlo nel metodo __init__. Allora il vostro codice sarebbe:

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


theExample = Example() 
print(theExample.itsProblem) 

Ma se si vuole una variabile di classe vera, quindi utilizzare il nome della classe direttamente:

class Example(object): 
    itsProblem = "problem" 


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

Ma attenzione con questo, come theExample.itsProblem è impostato automaticamente per essere uguale a Example.itsProblem, ma non è la stessa variabile e può essere modificata indipendentemente.

Alcune spiegazioni

In Python, le variabili auto essere create dinamicamente. Perciò, è possibile effettuare le seguenti operazioni:

class Example(object): 
    pass 

Example.itsProblem = "problem" 

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

print Example.itsProblem == e.itsSecondProblem 

Stampe

veri

Pertanto, questo è esattamente ciò che si fa con gli esempi precedenti.

Infatti, in Python usiamo self come this, ma è un po 'di più. Self è il primo argomento di qualsiasi metodo oggetto poiché il primo argomento è sempre il riferimento all'oggetto. Questo è automatico, che tu lo chiami o meno.

Il che significa che si può fare:

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


theExample = Example() 
print(theExample.itsProblem) 

Oppure:

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


theExample = Example() 
print(theExample.itsProblem) 

E 'esattamente la stessa cosa. Il primo argomento di QUALSIASI metodo di oggetto è l'oggetto corrente, lo chiamiamo solo come convenzione self. E aggiungi solo una variabile a questo oggetto, nello stesso modo in cui lo faresti dall'esterno.

Ora, sulle variabili di classe.

Quando si esegue:

class Example(object): 
    itsProblem = "problem" 


theExample = Example() 
print(theExample.itsProblem) 

Si noterà per prima cosa impostiamo una classe variabile, quindi accediamo un oggetto (esempio) variabili. Non impostiamo mai questa variabile oggetto ma funziona, com'è possibile?

Bene, Python prova ad ottenere prima la variabile oggetto, ma se non riesce a trovarla, ti darà la variabile di classe. Attenzione: la variabile di classe è condivisa tra le istanze e la variabile oggetto non lo è.

In conclusione, non utilizzare mai le variabili di classe per impostare valori predefiniti per le variabili oggetto. Utilizzare __init__ per quello.

Alla fine, imparerai che le classi Python sono istanze e quindi oggetti stessi, il che fornisce nuove informazioni per comprendere quanto sopra. Torna indietro e leggi di nuovo più tardi, una volta che te ne rendi conto.

+0

+1 per __init__. Ecco a cosa serve – Abizern

+0

tu dici: "theExample.itsProblem è impostato automaticamente per essere uguale a Example.itsProblem, ma non è la stessa variabile e può essere modificato indipendentemente" - ma non è giusto, e la tua frase è fuorviante. Confido che tu sappia cosa sta succedendo lì, quindi suggerisco di riformulare che: "è la stessa variabile, ma può essere riconnessa indipendentemente per ogni oggetto". – jsbueno

+0

Sì, ma il binding è un concetto di qualcuno per un altro linguaggio di programmazione come Java o C (come sospetto sia l'OP) che è completamente sconosciuto. Quindi dovrei spiegare cos'è il binding, quindi il binding tardivo, quindi il problema con i riferimenti su oggetti mutabili. Sarebbe troppo lungo. Penso che a volte devi sacrificare la precisione sull'altare della comprensione. –

8

Si sta dichiarando una variabile locale, non una variabile di classe. Per impostare una variabile di istanza (attributi), utilizzare

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

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

Per impostare un (membro aka statica) class variable, utilizzare

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

Tranne che le variabili di classe sono dichiarate * una volta * a * livello di classe *. Il tuo modo lo reimposterà ad ogni istanza, questo in realtà non è ciò che desideri. Vedi anche http://stackoverflow.com/questions/2709821/python-self-explained per la logica alla base del sé esplicito. – delnan

0

Se si dispone di una funzione di esempio (vale a dire quella che viene passato di auto) è possibile utilizzare auto per ottenere un riferimento alla classe utilizzando self.__ __class__ __

Ad esempio nel seguente codice tornado crea un'istanza per gestire le richieste GET, ma possiamo ottenere la classe get_handler e usarla per contenere un client riak quindi non è necessario crearne uno per ogni richiesta.

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

Implementare la dichiarazione di reso come nell'esempio seguente! Dovresti essere bravo. Spero che aiuta qualcuno ...

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

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

È necessario correggere il rientro del codice. Ci sono anche risposte superiori a questa domanda e la tua risposta è una variazione di base su quelle risposte, non una soluzione alternativa ... –

Problemi correlati