2012-12-03 8 views
6

Czytanie kodu źródłowego Django natrafiłem na funkcję this. Jest to implementacja znacznika block.Dlaczego ustawić "prywatny" python atrybut z * poza * klasy?

Co mnie interesuje to, że są one ustawienie zmiennej z dwóch wiodących podkreślenia (__loaded_blocks) od poza instancję parser klasy (parser jest instancją Parser class). Szybki grep w kodzie źródłowym Django pokazuje, że ciąg loaded_blocks występuje tylko tutaj.

Nigdy wcześniej nie rozważałem możliwości użycia funkcji wymieszania z pythonem, ale w efekcie ukryję przed nią atrybut __loaded_blocks z parser! Aby przeczytać ten atrybut z metody parser, musisz odwołać się do getattr(self, "__loaded_blocks").

Czy mam rację, sądząc, że jest to tylko niezamierzony i nieużywany efekt uboczny wybranego atrybutu? Czy może jest to głębszy cel?

Ogólnie rzecz biorąc, dlaczego chcesz coś takiego zrobić?

EDIT: W celu wyjaśnienia, jestem w pełni świadomy, że tak długo, jak nie próbować uzyskać dostęp do atrybutu __loaded_blocks od sposobu parser, to będzie działać tak jak każdy inny atrybut, i że jest w rzeczywistości nie zaklętego atrybutu.

+2

bez celu, tylko Django ma brzydkiego kodu. – Keith

Odpowiedz

3

Nie sądzę Nazwa mangling odbędzie się podczas dodać obiekt wraz z przedrostkiem __ do instancji

z docs:

prywatna nazwa przekręcona: Gdy identyfikatorem, który występuje w tekstowo definicja klasy rozpoczyna się od dwóch lub więcej podkreślników, a nie kończy się na dwóch lub więcej podkreśleniach, jest uważana 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 przetworzony 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.

class Test: 
    pass 

test = Test() 
test.__hello = 'hii'  
test.__hello # hiii 

Choć nazwa nie jest zniekształcone to nadal oznacza to jako „prywatne” dla konsumenta kodu

+0

Och, zdaję sobie z tego sprawę. Ale jeśli utworzyłeś metodę w 'Test', która wydrukowałaby atrybut' __hello' po ustawieniu, nie byłaby w stanie, ponieważ faktycznie próbowałaby wydrukować atrybut '_Test__hello'. Jak już powiedziałem, taka metoda musiałaby używać 'getattr' do drukowania zewnętrznego zestawu atrybutów" __hello ". –

+0

@lazyr oo tak, widzę, co mówisz teraz! nie czytają go z metody i gdyby założyli, nie stworzyliby zmiennej z podwójnym podkreśleniem ... – dm03514

Powiązane problemy