2011-01-21 5 views
14

Próbuję zrozumieć trochę jak Python (2.6) dotyczy klasy, instancje i tak dalej, i w pewnym momencie, próbowałem ten kod:Zastępowanie zmiennych klasy w Pythonie

#/usr/bin/python2.6 

class Base(object): 
    default = "default value in base" 

    def __init__(self): 
     super(Base, self).__init__() 

    @classmethod 
    def showDefaultValue(cls, defl = default): 
     print "defl == %s" % (defl) 


class Descend(Base): 
    default = "default value in descend" 

    def __init__(self): 
     super(Descend, self).__init__() 

if __name__ == "__main__": 
    Descend.showDefaultValue() 

Wyjście is: "wartość domyślna w bazie"

Zastanawiam się, dlaczego pole "domyślne" nie jest przesłonięte przez klasę Descend ... Czy istnieje sposób, aby go zastąpić? Dlaczego nie jest nadpisywany?

Każda wskazówka (lub link do strony objaśniającej zostanie doceniony). Dziękuję Ci!

Odpowiedz

12

Zmienna klasy jest nadpisywana. Wypróbuj

@classmethod 
def showDefaultValue(cls): 
    print "defl == %s" % (cls.default,) 

Powód, dla którego nie działa, ma więcej wspólnego ze sposobem, w jaki Python traktuje domyślne argumenty dla funkcji niż z atrybutami klas. Domyślna wartość dla defl jest oceniana w momencie, gdy Python definiuje wiązanie dla showDefaultValue i jest to wykonywane dokładnie raz. Kiedy wywołujesz metodę, używana jest domyślna wartość, która została oceniona w momencie definicji.

W twoim przypadku defl został powiązany z wartością zmiennej default, tak jak to było podczas wykonywania formularza z klasą Base. Niezależnie od tego, jak później wywołasz showDefaultValue (tj. Przez Base lub przez Descend), ta wartość pozostaje stała we wszystkich kolejnych wywołaniach showDefaultValue.

12
def showDefaultValue(cls, defl=default): 

oznacza, że ​​default zostaje oszacowany po zdefiniowaniu funkcji, jak zwykle w Pythonie. Zatem definicja wygląda to wówczas:

def showDefaultValue(cls, defl="default value in base"): 

Ta wartość defl jest przechowywana jako domyślnej argumentu obiektu funkcyjnego i wykorzystywane podczas wywołać metodę bez argumentów. Możesz sprawdzić wartości domyślne funkcji takiej jak print Descend.showDefaultValue.im_self.default, aby to sprawdzić.

Jeśli chcesz uzyskać domyślną z obecnej klasy potem trzeba dostać go stamtąd:

@classmethod 
def showDefaultValue(cls, defl=None): 
    if defl is None: 
     defl = cls.default 
    print "defl == %s" % (defl)