6

Pisałem dekoratora, który musi uzyskać dostęp do prywatnych zmiennych i stwierdził tę rozbieżność. Czy ktoś może to wyjaśnić?Python "prywatne" mangling nazwy i instancja vs atrybuty klasy

(Python 2.5)

Naming maglowania działa zgodnie z oczekiwaniami dla atrybutów zdefiniowanych w klasie:

atrybuty instancji nie działa (i to jest sposób, w jaki mają robić to dobrze?)

>>> class Tester(object): 
...  def __init__(self): 
...   self.__foo = "hi" 

>>> t = Tester() 
>>> t._Tester__foo 
AttributeError: 'Tester' object has no attribute '_Tester__foo' 

PS Czy "atrybut klasy" jest właściwym słowem? Oni nie są statyczne, ale jeśli jeden z tych listę lub jakiś inny zmienny typ, jest on dzielony ...

Aktualizacja

W rzeczywistości, drugi przykład działa dobrze, zbyt. To był problem ze sprzętem (ponowne uruchomienie pomogło).

+2

Atrybutem klasy jest właściwe słowo. I są * zawsze * dzielone. Mutability nie ma znaczenia. To prawie nigdy nie ma znaczenia, z wyjątkiem pytania, czy możesz zmutować dany obiekt. – delnan

+0

Czy mogę odrzucić to pytanie? Czy ktoś widzi wartość w utrzymaniu go? Nie mogę odtworzyć mojego pierwotnego problemu. Wydaje się działać zgodnie z oczekiwaniami. – Rafe

+1

Raczej zostaw to, ponieważ @MartijnPieters przeszedł całą procedurę testowania problemu w wielu testach Pythona. – jsbueno

Odpowiedz

9

To jest właściwie , a nie prawidłowe.

Łamanie nazw ma miejsce w czasie tworzenia klasy; wszelkie funkcje odnoszące się do zniekształconych nazw są również dostosowane.

I nie można odtworzyć swój przykład, przynajmniej nie w Python w wersji 2.4, 2.5, 2.6, 3.1 i 3.2 na Mac:

>>> class Tester(object): 
...  def __init__(self): 
...   self.__foo = "hi" 
... 
>>> Tester()._Tester__foo 
'hi' 
>>> Tester().__foo 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'Tester' object has no attribute '__foo' 

Jeśli demontować kodu bajtowego funkcji można zobaczyć nazwy zostały zniekształcone a także:

>>> import dis 
>>> dis.dis(Tester.__init__) 
    3   0 LOAD_CONST    1 ('hi') 
       3 LOAD_FAST    0 (self) 
       6 STORE_ATTR    1 (_Tester__foo) 
       9 LOAD_CONST    0 (None) 
      12 RETURN_VALUE   

Sprawdziłem compiler source i wszystkie nazwy są uruchamiane przez Mangler, ścieżki kodu, który pozostał ten sam od 2002 roku co najmniej.

I tak, atrybuty klas i atrybuty instancji są poprawnymi terminami. Atrybuty klas są zawsze udostępniane, ale przypisanie do atrybutu instancji przypisuje instancję. Mutowanie listy lub innych zmieniających się obiektów nie jest tym samym, co przypisanie atrybutu.

+0

Działa również z 3.2. – delnan

+0

Masz rację. Nie mam pojęcia, co się tam stało. Zdarzyło mi się zrestartować komputer, więc muszę go nazwać problemem informatycznym: "Czy próbowałeś go wyłączyć i ponownie włączyć?" ;) – Rafe