2014-04-26 10 views
9

myślałem, że były takie same przed wpadłem ten kod:Jaka jest różnica między getattr (self, "__a") a self .__ a w python?

class B(object): 
    def show(self): 
     self.__a = "test" 
     print "B" 

    def this_b(self): 
     print "this_b" 
     print self.__a 
     print getattr(self, '__a') #exception 


class C(B): 
    def show(self): 
     print "C" 
     # B.show(self) 
     super(C, self).show() 


    def call(self): 
     print "call" 
     self.show() 
     self.this_b() 
     # print self.__a 

C().call() 

podnosi AttributeError: 'C' object has no attribute '__a' ze stwierdzeniem getattr, ale dlaczego?

+3

bo [nazwa przekręcona] (https://docs.python.org/2/tutorial/classes.html# private-variables-and-class-local-references). – nneonneo

+0

Ogólnie rzecz biorąc, używanie nazw atrybutów "__" z prefiksem jest odradzane w Pythonie na korzyść tylko jednego podkreślenia. –

+2

@ErikAllik: Nie jestem pewien, czy kiedykolwiek został zachęcony. Zawsze był dostępny wyłącznie dla zmiennych, które powinny być chronione przed przypadkowym nadpisaniem w klasie pochodnej. – nneonneo

Odpowiedz

9

To właśnie z powodu Private name mangling.

nazwa Prywatna mangling: Gdy identyfikatorem, który tekstowo występuje w definicji klasy zaczyna się od dwóch lub więcej znaków podkreślenia i nie kończy się w dwóch lub więcej podkreślenia, uważa się prywatna nazwa tej klasy. Nazwy prywatne są przekształcane na dłuższą formę przed wygenerowaniem kodu dla nich. Transformacja wstawia nazwę klasy, z usuniętymi podkreślnikami przedrostkowymi i wstawionym pojedynczym podkreśleniem przed nazwą. Na przykład identyfikator __spam występujący w klasie o nazwie Ham zostanie przekształcony na _Ham__spam. Ta transformacja jest niezależna od kontekstu syntaktycznego, w którym używany jest identyfikator. Jeśli przekształcona nazwa jest bardzo długa (dłuższa niż 255 znaków), może wystąpić zdarzenie o zdefiniowanej implementacji. Jeśli nazwa klasy składa się tylko z podkreśleń, transformacja nie jest wykonywana.

Kiedy robisz

self.__a 

prywatna nazwa mangling zostaną załatwione automatycznie. Ale kiedy robisz

print getattr(self, '__a') 

trzeba zrobić to ręcznie, jak to

print getattr(self, '_B__a') 
# test 
+1

ładne wyjaśnienie! – LeoShi

Powiązane problemy