6

jestem nieco zdezorientowany tego zachowania (przy użyciu Pythona 3.2):Python podwójne podkreślenia maglowania

class Bar: 
    pass 

bar = Bar() 
bar.__cache = None 
print(vars(bar))  # {'__cache': None} 

class Foo: 
    def __init__(self): 
     self.__cache = None 

foo = Foo() 
print(vars(foo))  # {'_Foo__cache': None} 

Czytałem się trochę o tym, jak podwójne podkreślenia powodować nazw atrybutów być „zniekształcone”, ale Spodziewałbym się tego samego wymieszania nazw w obu przypadkach powyżej.

What is the meaning of a single- and a double-underscore before an object name?

jakieś pomysły, co tu się dzieje?

+4

Celem łamania jest właśnie ** zapobieganie ** twojemu drugiemu przypadkowi nie działa poprawnie. Zamiarem jest ukrycie atrybutu z kodu zewnętrznego. – millimoose

Odpowiedz

10

Nazwa maglowania występuje podczas oceny na class oświadczeniu. W przypadku atrybutu Bar atrybut __cache nie jest zdefiniowany jako część klasy, ale jest dodawany do określonego obiektu po fakcie.

(Właściwie to może nie być całkowicie poprawne .Mindowanie nazwy może wystąpić podczas oceny metody __new__, ale nie wiem, ale niezależnie, Twój __cache jest dodawany jawnie do pojedynczego obiektu, a nie dodawany przez kod klasy .)

+4

To jest zniekształcone podczas kompilacji. Możesz użyć funkcji 'dis.dis()', aby to zobaczyć, uruchom 'import dis; dis.dis (Foo .__ init __) ', aby zobaczyć, że nazwa została już zmanipulowana. –

+0

bardzo pomocne, thx za wyjaśnienie – gnr

7

Z docs

prywatne Nazwa przekręcona: Gdy identyfikatorem, który tekstowo występuje w definicji klasy zaczyna z dwoma lub więcej znaków podkreślenia i nie kończy się w dwóch lub więcej podkreślenia, że ​​jest uznano za prywatną nazwę tej klasy. Nazwy prywatne są przekształcane na dłuższą formę przed wygenerowaniem dla nich kodu. Transformacja wstawia nazwę klasy przed nazwą, z usuniętymi podkreślnikami podkreślenia i jednym znakiem podkreślenia wstawionym przed nazwą klasy. Na przykład identyfikator __spam występujący w klasie o nazwie Szynka będzie przekształcona na _Ham__spam. Ta transformacja jest niezależna od kontekstu syntaktycznego , w którym używany jest identyfikator. Jeśli przekształcona nazwa jest wyjątkowo długa (dłuższa niż 255 znaków), może wystąpić zdarzenie o zdefiniowanej implementacji. Jeśli nazwa klasy zawiera tylko podkreślenia, nie zostanie wykonana transformacja.

Jesteś przypisując swoją nieruchomość po klasa została zdefiniowana

+0

Link do dokumentów jest zepsuty –