Zniekształcenie nazwy w Pythonie


110

W innych językach ogólną wskazówką, która pomaga tworzyć lepszy kod, jest zawsze maksymalne ukrycie wszystkiego. Jeśli masz wątpliwości, czy zmienna powinna być prywatna, czy chroniona, lepiej wybrać prywatną.

Czy to samo dotyczy Pythona? Czy powinienem najpierw użyć dwóch wiodących znaków podkreślenia na wszystkim i tylko sprawić, by były mniej ukryte (tylko jeden podkreślenie), gdy ich potrzebuję?

Jeśli konwencja ma używać tylko jednego podkreślenia, chciałbym również poznać uzasadnienie.

Oto komentarz, który zostawiłem na temat odpowiedzi JBernardo . Wyjaśnia, dlaczego zadałem to pytanie, a także dlaczego chciałbym wiedzieć, dlaczego Python różni się od innych języków:

Pochodzę z języków, które uczą cię myśleć, że wszystko powinno być publiczne tylko w razie potrzeby i nic więcej. Rozumowanie jest takie, że zmniejszy to zależności i sprawi, że kod będzie bezpieczniejszy do zmiany. Sposób, w jaki Python robi rzeczy w odwrotnej kolejności - zaczynając od publicznych i idąc w kierunku ukrytych - jest dla mnie dziwny.

Odpowiedzi:


182

W razie wątpliwości pozostaw to „publiczne” - to znaczy nie dodawaj niczego, co mogłoby zasłaniać nazwę swojego atrybutu. Jeśli masz klasę z jakąś wartością wewnętrzną, nie przejmuj się tym. Zamiast pisać:

class Stack(object):

    def __init__(self):
        self.__storage = [] # Too uptight

    def push(self, value):
        self.__storage.append(value)

napisz to domyślnie:

class Stack(object):

    def __init__(self):
        self.storage = [] # No mangling

    def push(self, value):
        self.storage.append(value)

To z pewnością kontrowersyjny sposób robienia rzeczy. Nowicjusze w Pythonie po prostu go nienawidzą, a nawet niektórzy starzy faceci w Pythonie gardzą tym domyślnym - ale i tak jest to ustawienie domyślne, więc naprawdę polecam ci go przestrzegać, nawet jeśli czujesz się nieswojo.

Jeśli naprawdę chcesz wysłać wiadomość „Nie możesz tego dotknąć!” użytkownikom, zwykle poprzedza się zmienną jednym podkreśleniem. To tylko konwencja, ale ludzie ją rozumieją i podwójnie ostrożnie obchodzą się z takimi rzeczami:

class Stack(object):

    def __init__(self):
        self._storage = [] # This is ok but pythonistas use it to be relaxed about it

    def push(self, value):
        self._storage.append(value)

Może to być również przydatne, aby uniknąć konfliktu między nazwami właściwości i nazwami atrybutów:

 class Person(object):
     def __init__(self, name, age):
         self.name = name
         self._age = age if age >= 0 else 0

     @property
     def age(self):
         return self._age

     @age.setter
     def age(self, age):
         if age >= 0:
             self._age = age
         else:
             self._age  = 0

A co z podwójnym podkreśleniem? Cóż, magia podwójnego podkreślenia jest używana głównie w celu uniknięcia przypadkowego przeładowania metod i konfliktów nazw z atrybutami nadklas . Może to być całkiem przydatne, jeśli napiszesz klasę, która ma być wielokrotnie przedłużana.

Jeśli chcesz go użyć do innych celów, możesz, ale nie jest to ani zwyczajne, ani zalecane.

EDYCJA : Dlaczego tak jest? Cóż, zwykły styl Pythona nie kładzie nacisku na prywatność - wręcz przeciwnie! Powodów jest wiele - większość z nich jest kontrowersyjna ... Zobaczmy kilka z nich.

Python ma właściwości

Większość języków OO stosuje obecnie odwrotne podejście: to, czego nie powinno się używać, nie powinno być widoczne, więc atrybuty powinny być prywatne. Teoretycznie dałoby to łatwiejsze w zarządzaniu, mniej powiązane ze sobą klasy, ponieważ nikt nie zmieniałby lekkomyślnie wartości wewnątrz obiektów.

Jednak nie jest to takie proste. Na przykład klasy Java mają wiele atrybutów i metod pobierających, które pobierają tylko wartości i metody ustawiające, które po prostu ustawiają wartości. Powiedzmy, że potrzebujesz, powiedzmy, siedmiu linii kodu, aby zadeklarować pojedynczy atrybut - który programista Pythona powiedziałby, że jest niepotrzebnie złożony. Ponadto w praktyce po prostu piszesz całą masę kodu, aby uzyskać jedno pole publiczne, ponieważ możesz zmienić jego wartość za pomocą metod pobierających i ustawiających.

Dlaczego więc stosować tę domyślną zasadę prywatności? Po prostu ustaw domyślnie swoje atrybuty jako publiczne. Oczywiście jest to problematyczne w Javie, ponieważ jeśli zdecydujesz się dodać walidację do swojego atrybutu, wymagałoby to zmiany wszystkich

person.age = age;

w swoim kodzie, powiedzmy,

person.setAge(age);

setAge() istota:

public void setAge(int age) {
    if (age >= 0) {
        this.age = age;
    } else {
        this.age = 0;
    }
}

Tak więc w Javie (i innych językach) domyślnie i tak są używane metody pobierające i ustawiające, ponieważ ich pisanie może być denerwujące, ale może zaoszczędzić dużo czasu, jeśli znajdziesz się w opisanej przeze mnie sytuacji.

Jednak nie musisz tego robić w Pythonie, ponieważ Python ma właściwości. Jeśli masz tę klasę:

 class Person(object):
     def __init__(self, name, age):
         self.name = name
         self.age = age

a następnie decydujesz się na walidację wieku, nie musisz zmieniać person.age = agefragmentów swojego kodu. Po prostu dodaj właściwość (jak pokazano poniżej)

 class Person(object):
     def __init__(self, name, age):
         self.name = name
         self._age = age if age >= 0 else 0

     @property
     def age(self):
         return self._age

     @age.setter
     def age(self, age):
         if age >= 0:
             self._age = age
         else:
             self._age  = 0

Jeśli możesz to zrobić i nadal używać person.age = age, dlaczego miałbyś dodawać pola prywatne oraz pobierające i ustawiające?

(Zobacz też, że Python to nie Java i ten artykuł o szkodliwości używania metod pobierających i ustawiających ).

Wszystko i tak jest widoczne - a próba ukrycia tylko komplikuje pracę

Nawet w językach, w których istnieją prywatne atrybuty, możesz uzyskać do nich dostęp za pośrednictwem jakiejś biblioteki refleksji / introspekcji. A ludzie robią to dużo, w ramach i dla rozwiązywania pilnych potrzeb. Problem polega na tym, że biblioteki introspekcji są po prostu trudnym sposobem robienia tego, co można zrobić z atrybutami publicznymi.

Ponieważ Python jest bardzo dynamicznym językiem, dodawanie tego obciążenia do swoich klas przyniesie po prostu efekt przeciwny do zamierzonego.

Problemu nie da się zobaczyć - trzeba go zobaczyć

Dla Pythonisty hermetyzacja to nie niemożność zobaczenia wewnętrznych elementów klas, ale możliwość uniknięcia patrzenia na nie. Chodzi mi o to, że hermetyzacja jest właściwością komponentu, która pozwala na jej użycie bez obawy użytkownika o wewnętrzne szczegóły. Jeśli możesz użyć komponentu bez zawracania sobie głowy jego implementacją, to jest on hermetyzowany (zdaniem programisty Pythona).

Teraz, jeśli napisałeś swoją klasę w taki sposób, że możesz jej używać bez zastanawiania się nad szczegółami implementacji, nie ma problemu, jeśli z jakiegoś powodu chcesz zajrzeć do klasy. Chodzi o to, że twoje API powinno być dobre, a reszta to szczegóły.

Guido tak powiedział

Cóż, to nie jest kontrowersyjne: tak naprawdę powiedział . (Poszukaj „otwartego kimona”).

To jest kultura

Tak, jest kilka powodów, ale nie ma krytycznego powodu. Jest to głównie kulturowy aspekt programowania w Pythonie. Szczerze mówiąc, może być też inaczej - ale tak nie jest. Możesz również równie łatwo zapytać na odwrót: dlaczego niektóre języki domyślnie używają atrybutów prywatnych? Z tego samego powodu, co w przypadku praktyki Pythona: ponieważ jest to kultura tych języków, a każdy wybór ma zalety i wady.

Ponieważ ta kultura już istnieje, zaleca się jej przestrzeganie. W przeciwnym razie denerwują Cię programiści Pythona, którzy każą ci usunąć __z kodu, gdy zadasz pytanie w przepełnieniu stosu :)


1. Hermetyzacja służy do ochrony niezmienników klas. Nie ukrywanie niepotrzebnych szczegółów przed światem zewnętrznym, ponieważ byłoby to irytujące. 2. „Chodzi o to, że twój interfejs API powinien być dobry, a reszta to szczegóły”. To prawda. Atrybuty publiczne są częścią twojego API. Ponadto czasami publiczne metody ustawiające są odpowiednie (w odniesieniu do niezmienników klas), a czasami nie. API, które ma publiczne metody ustawiające, które nie powinny być publiczne (ryzyko naruszenia niezmienników) jest złym API. Oznacza to, że i tak musisz pomyśleć o widoczności każdego ustawiającego, a posiadanie „wartości domyślnej” oznacza mniej.
Jowisz

21

Po pierwsze - co to jest zniekształcanie nazw?

Zniekształcanie nazw jest wywoływane, gdy znajdujesz się w definicji klasy i używasz __any_namelub __any_name_, to znaczy dwóch (lub więcej) wiodących znaków podkreślenia i co najwyżej jednego końcowego podkreślenia.

class Demo:
    __any_name = "__any_name"
    __any_other_name_ = "__any_other_name_"

I teraz:

>>> [n for n in dir(Demo) if 'any' in n]
['_Demo__any_name', '_Demo__any_other_name_']
>>> Demo._Demo__any_name
'__any_name'
>>> Demo._Demo__any_other_name_
'__any_other_name_'

Kiedy masz wątpliwości, co zrobić?

Pozornym użyciem jest uniemożliwienie podklasom używania atrybutu używanego przez klasę.

Potencjalną wartością jest unikanie kolizji nazw z podklasami, które chcą przesłonić zachowanie, tak aby funkcje klasy nadrzędnej działały zgodnie z oczekiwaniami. Jednak przykład w dokumentacji Pythona nie jest zastępowalny przez Liskov i nie przychodzą mi do głowy żadne przykłady, w których uznałem to za przydatne.

Wadą jest to, że zwiększa obciążenie poznawcze do odczytu i zrozumienia podstawy kodu, a zwłaszcza podczas debugowania, w którym widzisz nazwę podwójnego podkreślenia w źródle i zniekształconą nazwę w debugerze.

Moje osobiste podejście polega na celowym unikaniu tego. Pracuję na bardzo dużej bazie kodu. Rzadkie zastosowania tego wystają jak ból kciuka i nie wydają się uzasadnione.

Musisz być tego świadomy, aby wiedzieć, kiedy to widzisz.

PEP 8

PEP 8 , przewodnik po stylach bibliotek standardowych w Pythonie, mówi obecnie (w skrócie):

Istnieją pewne kontrowersje dotyczące używania __names.

Jeśli twoja klasa ma być podklasą i masz atrybuty, których nie chcesz używać w podklasach, rozważ nazwanie ich podwójnymi początkowymi podkreśleniami i bez końcowych podkreślników.

  1. Zwróć uwagę, że w zniekształconej nazwie jest używana tylko prosta nazwa klasy, więc jeśli podklasa wybierze zarówno tę samą nazwę klasy, jak i nazwę atrybutu, nadal możesz uzyskać kolizje nazw.

  2. Zniekształcanie nazw może sprawić, że niektóre zastosowania, takie jak debugowanie __getattr__(), będą mniej wygodne. Jednak algorytm zmiany nazwy jest dobrze udokumentowany i łatwy do wykonania ręcznie.

  3. Nie każdy lubi zniekształcanie nazwisk. Spróbuj zrównoważyć potrzebę unikania przypadkowych kolizji nazw z potencjalnym użyciem przez zaawansowanych rozmówców.

Jak to działa?

Jeśli w definicji klasy wstawisz dwa podkreślenia (bez kończenia podwójnych podkreśleń), nazwa zostanie zniekształcona, a na obiekcie zostanie dodany znak podkreślenia, po którym nastąpi nazwa klasy:

>>> class Foo(object):
...     __foobar = None
...     _foobaz = None
...     __fooquux__ = None
... 
>>> [name for name in dir(Foo) if 'foo' in name]
['_Foo__foobar', '__fooquux__', '_foobaz']

Zwróć uwagę, że nazwy zostaną zniekształcone tylko podczas analizowania definicji klasy:

>>> Foo.__test = None
>>> Foo.__test
>>> Foo._Foo__test
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'Foo' has no attribute '_Foo__test'

Ponadto nowi w Pythonie czasami mają problemy ze zrozumieniem, co się dzieje, gdy nie mogą ręcznie uzyskać dostępu do nazwy, którą widzą w definicji klasy. To nie jest silny powód przeciwko temu, ale warto to rozważyć, jeśli masz uczących się odbiorców.

Jedno podkreślenie?

Jeśli konwencja ma używać tylko jednego podkreślenia, chciałbym również poznać uzasadnienie.

Kiedy zamierzam, aby użytkownicy trzymali ręce z dala od atrybutu, zwykle używam tylko jednego podkreślenia, ale to dlatego, że w moim modelu mentalnym podklasy miałyby dostęp do nazwy (którą zawsze mają, ponieważ mogą łatwo zauważyć i tak zniekształcona nazwa).

Gdybym przeglądał kod, który używa __prefiksu, zapytałbym, dlaczego wywołują zniekształcanie nazw i czy nie mogliby równie dobrze poradzić sobie z pojedynczym podkreśleniem, pamiętając, że jeśli podklasy wybierają te same nazwy dla klasy i class mimo to nastąpi kolizja nazw.


16

Nie powiedziałbym, że praktyka tworzy lepszy kod. Modyfikatory widoczności tylko odwracają uwagę od wykonywanego zadania, a jako efekt uboczny wymuszają używanie interfejsu zgodnie z zamierzeniami. Ogólnie rzecz biorąc, wymuszanie widoczności uniemożliwia programistom zepsucie rzeczy, jeśli nie przeczytali poprawnie dokumentacji.

O wiele lepszym rozwiązaniem jest trasa, którą zachęca Python: Twoje klasy i zmienne powinny być dobrze udokumentowane, a ich zachowanie jasne. Źródło powinno być dostępne. Jest to znacznie bardziej rozszerzalny i niezawodny sposób pisania kodu.

Moja strategia w Pythonie jest taka:

  1. Po prostu napisz to cholerstwo, nie rób żadnych założeń co do tego, jak Twoje dane powinny być chronione. Zakłada się, że piszesz, aby stworzyć idealne interfejsy dla swoich problemów.
  2. Użyj początkowego podkreślenia dla rzeczy, które prawdopodobnie nie będą używane zewnętrznie i nie są częścią normalnego interfejsu „kodu klienta”.
  3. Podwójnego podkreślenia używaj tylko w przypadku rzeczy, które są czysto wygodne w klasie lub spowodują znaczne szkody, jeśli zostaną przypadkowo odkryte.

Przede wszystkim powinno być jasne, co robi wszystko. Udokumentuj to, jeśli ktoś inny będzie go używał. Udokumentuj to, jeśli chcesz, aby było przydatne za rok.

Na marginesie, w tych innych językach powinieneś korzystać z opcji chronionych : nigdy nie wiesz, że Twoja klasa może zostać później odziedziczona i do czego może zostać użyta. Najlepiej jest chronić tylko te zmienne, co do których jesteś pewien, że nie mogą lub nie powinny być używane przez obcy kod.


9

Nie powinieneś zaczynać od prywatnych danych i upubliczniać je w razie potrzeby. Zamiast tego powinieneś zacząć od określenia interfejsu twojego obiektu. Oznacza to, że powinieneś zacząć od ustalenia, co widzi świat (rzeczy publiczne), a następnie dowiedzieć się, jakie prywatne rzeczy są niezbędne, aby tak się stało.

Inny język utrudnia upublicznienie tego, co kiedyś było publiczne. Tzn. Zepsuję dużo kodu, jeśli ustawię moją zmienną jako prywatną lub chronioną. Ale w przypadku właściwości w Pythonie tak nie jest. Raczej mogę zachować ten sam interfejs nawet przy zmianie układu danych wewnętrznych.

Różnica między _ a __ polega na tym, że Python faktycznie próbuje wymusić to drugie. Oczywiście nie jest to bardzo trudne, ale to utrudnia. Mając _ tylko mówi innym programistom, jaki jest zamiar, mogą zignorować na własne ryzyko. Ale ignorowanie tej zasady jest czasami pomocne. Przykłady obejmują debugowanie, tymczasowe hacki i pracę z kodem innej firmy, który nie był przeznaczony do użytku w sposób, w jaki go używasz.


6

Jest już na to wiele dobrych odpowiedzi, ale mam zamiar zaproponować inną. Jest to również częściowo odpowiedź dla ludzi, którzy powtarzają, że podwójne podkreślenie nie jest prywatne (tak naprawdę jest).

Jeśli spojrzysz na Javę / C #, oba mają prywatne / chronione / publiczne. Wszystkie te są konstrukcjami w czasie kompilacji . Są one egzekwowane dopiero w momencie kompilacji. Gdybyś miał użyć odbicia w Javie / C #, mógłbyś łatwo uzyskać dostęp do metody prywatnej.

Teraz za każdym razem, gdy wywołujesz funkcję w Pythonie, z natury korzystasz z odbicia. Te fragmenty kodu są takie same w Pythonie.

lst = []
lst.append(1)
getattr(lst, 'append')(1)

Składnia „kropki” jest tylko cukrem składniowym dla drugiego fragmentu kodu. Głównie dlatego, że używanie getattr jest już brzydkie przy tylko jednym wywołaniu funkcji. Stamtąd jest tylko gorzej.

W związku z tym nie może istnieć prywatna wersja Java / C #, ponieważ Python nie kompiluje kodu. Java i C # nie mogą sprawdzić, czy funkcja jest prywatna czy publiczna w czasie wykonywania, ponieważ ta informacja zniknęła (i nie ma wiedzy o tym, skąd funkcja jest wywoływana).

Teraz, mając te informacje, zniekształcenie nazwy podwójnego podkreślenia jest najbardziej sensowne dla osiągnięcia „prywatności”. Teraz, gdy funkcja jest wywoływana z instancji „self” i zauważa, że ​​zaczyna się od „__”, po prostu wykonuje tam zniekształcenie nazwy. To po prostu więcej cukru syntaktycznego. Ten cukier składniowy dopuszcza odpowiednik słowa „prywatny” w języku, który używa odbicia jedynie w celu uzyskania dostępu do elementów danych.

Zastrzeżenie: nigdy nie słyszałem, aby ktokolwiek z programistów Pythona powiedział coś takiego. Prawdziwym powodem braku „prywatnego” jest kultura, ale zauważysz także, że większość języków skryptowych / interpretowanych nie ma języka prywatnego. Ściśle egzekwowalny prywatny nie jest praktyczny w żadnym wypadku, z wyjątkiem czasu kompilacji.


4

Po pierwsze: dlaczego chcesz ukryć swoje dane? Dlaczego to takie ważne?

W większości przypadków nie chcesz tego robić, ale robisz to, ponieważ robią to inni.

Jeśli naprawdę naprawdę nie chcesz, aby ludzie czegoś używali, dodaj przed sobą jeden podkreślenie. To wszystko ... Pythonistas wiedzą, że rzeczy z jednym podkreśleniem nie są gwarantowane za każdym razem i mogą ulec zmianie bez Twojej wiedzy.

Tak właśnie żyjemy i nie przeszkadza nam to.

Użycie dwóch podkreśleń sprawi, że Twoja klasa będzie tak źle podklasowa, że ​​nawet ty nie będziesz chciał pracować w ten sposób.


2
Pominąłeś powód, dla którego podwójne podkreślenie jest złe w tworzeniu podklas ... poprawiłoby to twoją odpowiedź.
Matt Joiner,

2
Biorąc pod uwagę, że podwójne podkreślenia tak naprawdę służą tylko do zapobiegania kolizjom nazw z podklasami (jako sposób na powiedzenie „ręce precz” do podklas), nie widzę, w jaki sposób zniekształcanie nazw stwarza problem.
Aaron Hall

4

Wybrana odpowiedź dobrze radzi sobie z wyjaśnieniem, w jaki sposób właściwości eliminują potrzebę prywatnych atrybutów , ale dodałbym również, że funkcje na poziomie modułu eliminują potrzebę prywatnych metod .

Jeśli zmienisz metodę w funkcję na poziomie modułu, usuniesz możliwość zastąpienia jej przez podklasy. Przeniesienie niektórych funkcji na poziom modułu jest bardziej Pythonowe niż próba ukrycia metod z zniekształcaniem nazw.


3

Poniższy fragment kodu wyjaśni wszystkie różne przypadki:

  • dwa wiodące podkreślenia (__a)
  • pojedynczy wiodący podkreślnik (_a)
  • bez podkreślenia (a)

    class Test:
    
    def __init__(self):
        self.__a = 'test1'
        self._a = 'test2'
        self.a = 'test3'
    
    def change_value(self,value):
        self.__a = value
        return self.__a

drukowanie wszystkich poprawnych atrybutów obiektu testowego

testObj1 = Test()
valid_attributes = dir(testObj1)
print valid_attributes

['_Test__a', '__doc__', '__init__', '__module__', '_a', 'a', 
'change_value']

Tutaj możesz zobaczyć, że nazwa __a została zmieniona na _Test__a, aby zapobiec nadpisaniu tej zmiennej przez jakąkolwiek podklasę. Ta koncepcja jest znana w Pythonie jako „zniekształcanie nazw”. Możesz uzyskać dostęp do tego w następujący sposób:

testObj2 = Test()
print testObj2._Test__a

test1

Podobnie, w przypadku _a, zmienna ma po prostu powiadomić dewelopera, że ​​powinna być używana jako zmienna wewnętrzna tej klasy, interpreter Pythona nic nie zrobi, nawet jeśli uzyskasz do niego dostęp, ale nie jest to dobra praktyka.

testObj3 = Test()
print testObj3._a

test2

zmienna może być dostępna z dowolnego miejsca, jest podobna do publicznej zmiennej klasy.

testObj4 = Test()
print testObj4.a

test3

Mam nadzieję, że odpowiedź ci pomogła :)


2

Na pierwszy rzut oka powinno być to samo, co w przypadku innych języków (pod „innymi” mam na myśli Javę lub C ++), ale tak nie jest.

W Javie ustawiłeś wszystkie zmienne jako prywatne, które nie powinny być dostępne na zewnątrz. Jednocześnie w Pythonie nie można tego osiągnąć, ponieważ nie ma „prywatności” (jak mówi jedna z zasad Pythona - „Wszyscy jesteśmy dorośli”). Tak więc podwójne podkreślenie oznacza tylko „Chłopaki, nie używaj tego pola bezpośrednio”. To samo znaczenie ma pojedyncze podkreślenie, które jednocześnie nie powoduje bólu głowy, gdy trzeba dziedziczyć z rozważanej klasy (tylko przykład możliwego problemu spowodowanego podwójnym podkreśleniem).

Tak więc radziłbym domyślnie używać pojedynczego podkreślenia dla członków „prywatnych”.


Użyj podwójnego podkreślenia dla „prywatnego” i pojedynczego podkreślenia dla „chronionego”. Zwykle ludzie używają po prostu pojedynczego podkreślenia do wszystkiego (podwójne podkreślenie pomoże wymusić prywatność, co zwykle jest sprzeczne ze stylem Pythona).
Jonathan Sternberg

1
Ale czy to nie sprawia, że ​​dwa podkreślenia są podobne do prywatnych, a jedno podkreślenie do chronionych? Dlaczego nie zacząć od „prywatnego”?
Paul Manta

@Paul Nie, tak nie jest. W Pythonie nie ma prywatności i nie powinieneś próbować tego osiągnąć.
Roman Bodnarchuk,

@Roman Mówiąc koncepcyjnie ... Zwróć uwagę na cudzysłowy „prywatne”.
Paul Manta

1

„W przypadku wątpliwości, czy zmienna powinna być prywatna, czy chroniona, lepiej wybrać opcję prywatną”. - tak, to samo dotyczy Pythona.

Niektóre odpowiedzi mówią o „konwencjach”, ale nie podawaj linków do tych konwencji. W autorytatywnym przewodniku po Pythonie, PEP 8 wyraźnie stwierdza:

W razie wątpliwości wybierz opcję niepubliczną; łatwiej jest go później upublicznić niż uczynić atrybut publiczny niepublicznym.

W innych odpowiedziach uwzględniono rozróżnienie między publicznym i prywatnym oraz zniekształcanie nazw w Pythonie. Z tego samego linku

Nie używamy tutaj terminu „prywatny”, ponieważ żaden atrybut nie jest tak naprawdę prywatny w Pythonie (bez generalnie niepotrzebnej ilości pracy).


-2

# PRZYKŁADOWY PROGRAM ZMIANY NAZW Pythona

class Demo:
    __any_name = "__any_name"
    __any_other_name_ = "__any_other_name_"


[n for n in dir(Demo) if 'any' in n]   # GIVES OUTPUT AS ['_Demo__any_name', 
                                       #    '_Demo__any_other_name_']

1
To w ogóle nie odpowiada na pytanie - pokazuje przykład, ale nie dociera do sedna pytania. To i to pytanie ma prawie 9 lat z zaakceptowaną odpowiedzią. Czy to dodaje coś do odpowiedzi już tu podanych?
rayryeng
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.