Podczas pracy z pythonem po raz pierwszy odkryłem, że kończę pisanie wielu klas w tym samym pliku, co jest sprzeczne z innymi językami, takimi jak Java, która używa jednego pliku na klasę.
Zazwyczaj klasy te składają się z 1 abstrakcyjnej klasy bazowej, z 1-2 konkretnymi implementacjami, których użycie różni się nieznacznie. Poniżej zamieściłem jeden taki plik:
class Logger(object):
def __init__(self, path, fileName):
self.logFile = open(path + '/' + filename, 'w+')
self.logFile.seek(0, 2)
def log(self, stringtoLog):
self.logFile.write(stringToLog)
def __del__(self):
self.logFile.close()
class TestLogger(Logger):
def __init__(self, serialNumber):
Logger.__init__('/tests/ModuleName', serialNumber):
def readStatusLine(self):
self.logFile.seek(0,0)
statusLine = self.logFile.readLine()
self.logFile.seek(0,2)
return StatusLine
def modifyStatusLine(self, newStatusLine):
self.logFile.seek(0,0)
self.logFile.write(newStatusLine)
self.logFile.seek(0,2)
class GenericLogger(Logger):
def __init__(self, fileName):
Logger.__init__('/tests/GPIO', fileName):
def logGPIOError(self, errorCode):
self.logFile.write(str(errorCode))
Jak widać powyżej, mam klasę bazową Logger, z kilkoma różnicami w implementacji poniżej.
Pytanie: Czy ten standard jest dla Pythona, czy dla dowolnego języka? Jakie problemy mogą wyniknąć z korzystania z tej implementacji, jeśli występują?
EDYCJA: Tak naprawdę nie szukam wskazówek na temat tego konkretnego pliku, ale w bardziej ogólnym sensie. Co jeśli klasy zakończyły się 3-5 umiarkowanie złożonymi metodami? Czy miałoby to sens, aby je podzielić? Gdzie jest granica dla powiedzenia, że powinieneś podzielić plik?
Odpowiedzi:
W porządku. Dla odniesienia jest również w C ++.
Utrzymywanie ściśle ze sobą powiązanych rzeczy to rozsądna praktyka. Unikanie niewłaściwego łączenia jest również dobrą praktyką. Znalezienie właściwej równowagi nie jest kwestią ścisłych zasad, ale, no cóż, znalezienia równowagi między różnymi problemami.
Kilka praktycznych zasad:
Rozmiar
Zbyt duże pliki mogą być brzydkie, ale w tym przypadku tak nie jest. Brzydota jest prawdopodobnie wystarczającym powodem do podzielenia pliku, ale rozwijanie tego wyczucia estetycznego jest w dużej mierze kwestią doświadczenia, więc nie pomaga ci dowiedzieć się, co zrobić a priori
Rozdzielenie obaw
Jeśli Twoje konkretne implementacje mają bardzo różne obawy wewnętrzne, w jednym pliku gromadzone są wszystkie obawy. Na przykład implementacje z nie nakładającymi się na siebie zależnościami sprawiają, że pojedynczy plik zależy od sumy wszystkich tych zależności.
Czasami uzasadnione może być rozważenie powiązania podklas z ich zależnościami, które przeważają nad sprzężeniem z interfejsem (lub odwrotnie, problem implementacji interfejsu jest słabszy niż problem wewnętrzny związany z tą implementacją).
Jako konkretny przykład weź ogólny interfejs bazy danych. Konkretne implementacje wykorzystujące odpowiednio DB w pamięci, SQL RDBMS i zapytanie sieciowe mogą nie mieć nic wspólnego poza interfejsem, a zmuszanie wszystkich, którzy chcą, aby lekka wersja w pamięci importowała również bibliotekę SQL, jest paskudne.
Kapsułkowanie
Chociaż może napisać dobrze kapsułkach zajęcia w tym samym module, to mogłoby zachęcić niepotrzebnego sprzęgło tylko dlatego, że masz dostęp do szczegółów implementacyjnych, które w przeciwnym razie nie można wywieźć poza modułem.
Myślę, że to po prostu kiepski styl, ale możesz wymusić lepszą dyscyplinę, dzieląc moduł, jeśli naprawdę nie możesz zerwać z nałogiem.
źródło
Moje zwykłe dokumenty referencyjne, aby wiedzieć, co to jest python.
Z Zen Of Python
Od PEP 8
Moją interpretacją jest to, że wszystko jest w porządku, ponieważ byłoby proste i płaskie. Ponadto, ponieważ nazwy klas i nazwy plików mają różne przypadki, i tak nie powinny być identyczne, więc nie widziałbym problemu w pakowaniu wielu powiązanych klas w pliku.
źródło
To, co masz teraz, jest w porządku. Przejrzyj standardową bibliotekę - w jednym pliku jest mnóstwo modułów z wieloma powiązanymi klasami. W pewnym momencie sprawy stają się większe i ostatecznie będziesz chciał zacząć korzystać z modułów z wieloma plikami, ale nie ma prawdziwych reguł określających, kiedy. Rzeczy po prostu się dzielą, gdy jeden plik zaczyna wydawać się „za duży”.
źródło
Jest to zdecydowanie w porządku i zachęcam do posiadania kilku klas w jednym pliku, o ile są one realizowane. Ogólnie rzecz biorąc, twoje klasy powinny pozostać krótkie i zwięzłe i powinieneś raczej podzielić zachowanie na dwie lub więcej klas niż budować ogromne monolityczne. Podczas pisania kilku małych klas naprawdę konieczne i pomocne jest trzymanie tych, które są powiązane w tym samym pliku.
źródło
W skrócie - do diabła tak.
Co więcej, posiadanie wielu klas w jednym pliku jest czasami bardzo przydatne. Niektóre pakiety (
six
,bottle
) jawnie są dostarczane w jednym pliku, aby można je było łatwo zintegrować z dowolnym modułem innej firmy bez konieczności instalowania pip (czasem pożądane). Pamiętaj jednak, aby dobrze uporządkować kod. Intensywnie używaj komentarzy do kodu i bloków separacji, aby był bardziej czytelny.źródło