Klasa "prywatna" (implementacja) w Pythonie
Koduję mały moduł Pythona składający się z dwóch części:
- niektóre funkcje definiujące publiczny interfejs,
- Klasa implementacyjna używana przez powyższe funkcje, ale nie mająca znaczenia poza modułem.
Na początku zdecydowałem się "ukryć" tę klasę implementacji, definiując ją wewnątrz funkcji używając jej, ale to utrudnia czytelność i nie może być użyte, jeśli wiele funkcji używa ponownie tej samej klasy.
Więc oprócz komentarzy i docstrings, czy istnieje mechanizm oznaczający klasę jako "prywatną " lub"wewnętrzną"? Znam mechanizm podkreślenia, ale jak rozumiem, dotyczy to tylko zmiennych, funkcji i nazw metod.
7 answers
Użyj pojedynczego przedrostka podkreślenia:
class _Internal:
...
Jest to oficjalna Konwencja Pythona dla' wewnętrznych 'symboli;" from module import * " nie importuje obiektów z prefiksem podkreślenia.
Edit: odniesienie do konwencji pojedynczego podkreślenia
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-11 00:06:56
W skrócie:
Nie możesz egzekwować prywatności . W Pythonie nie ma prywatnych klas/metod/funkcji. Przynajmniej nie ścisła prywatność, jak w innych językach, takich jak Java.
Możesz tylko wskazać/zasugerować prywatność . Jest to zgodne z konwencją. Konwencja Pythona dotycząca oznaczania klasy/funkcji/metody jako prywatnej polega na poprzedzaniu jej znakiem _ (podkreślenie). Na przykład,
def _myfunc()
LUBclass _MyClass:
. Możesz również utworzyć pseudo-prywatność, wprowadzając metodę z dwoma podkreślnikami (np.:__foo
). Nie można uzyskać dostępu do metody bezpośrednio, ale nadal można ją wywołać przez specjalny prefiks używając nazwy klasy(np:_classname__foo
). Najlepsze, co możesz zrobić, to wskazać / zasugerować prywatność, a nie egzekwować ją.
Python jest pod tym względem jak perl. Parafrazując słynny tekst o prywatności z książki Perla, filozofia jest taka, że powinieneś trzymać się z dala od salonu, ponieważ nie byłeś zaproszony, a nie dlatego, że jest broniony strzelbą.
Dla więcej informacji:
- zmienne prywatne dokumentacja Pythona
- funkcje prywatne Dive into Python , by Mark Pilgrim
- dlaczego 'prywatne' metody Pythona nie są tak naprawdę prywatne? pytanie o StackOverflow 70528
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-21 13:49:50
Zdefiniuj __all__
, listę nazw, które chcesz wyeksportować (zobacz dokumentację ).
__all__ = ['public_class'] # don't add here the 'implementation_class'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-15 15:36:03
Wzór, który czasami używam jest taki:
Define a class:
class x(object):
def doThis(self):
...
def doThat(self):
...
Tworzy instancję klasy, nadpisując nazwę klasy:
x = x()
Zdefiniuj symbole eksponujące funkcjonalność:
doThis = x.doThis
doThat = x.doThat
Usuń samą instancję:
del x
Teraz masz moduł, który ujawnia tylko twoje publiczne funkcje.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-15 15:58:49
Konwencja jest poprzedzona znakiem " _ " do klas wewnętrznych, funkcji i zmiennych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-15 15:33:48
Aby zająć się kwestią konwencji projektowych, i jak powiedział Christopher, naprawdę nie ma czegoś takiego jak" prywatne " w Pythonie. Może to zabrzmieć dziwnie, jak na kogoś, kto pochodzi z C / C++ (jak ja jakiś czas temu), ale w końcu pewnie zdasz sobie sprawę, że przestrzeganie konwencji wystarczy.
Zobaczenie czegoś z podkreśleniem z przodu powinno być wystarczająco dobrą wskazówką, aby nie używać tego bezpośrednio. Jeśli interesuje Cię zaśmiecanie help(MyClass)
wyjścia (na które wszyscy patrzą, gdy szukając, jak używać klasy), podkreślone atrybuty / klasy nie są tam zawarte, więc skończysz po prostu mając opisany "publiczny" interfejs.
Plus, posiadanie wszystkiego, co publiczne, ma swoje niesamowite plusy, na przykład, możesz testować jednostki praktycznie wszystko z zewnątrz (czego nie możesz zrobić z C/C++ private constructs).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-15 18:09:59
Użyj dwóch podkreślników, aby przedrostki nazw" prywatnych " identyfikatorów. Dla klas w module, użyj pojedynczego podkreślnika wiodącego i nie będą one importowane za pomocą "from module import *".
class _MyInternalClass:
def __my_private_method:
pass
(nie ma czegoś takiego jak prawdziwe "prywatne" w Pythonie. Na przykład Python automatycznie zmienia nazwy członków klasy z podwójnymi podkreślnikami na __clssname_mymember
. Tak naprawdę, jeśli znasz zniekształconą nazwę, możesz użyć podmiotu "prywatnego" i tak. Zobacz tutaj. i oczywiście możesz wybrać aby ręcznie zaimportować klasy "wewnętrzne", jeśli chcesz).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-15 19:59:45