Zauważ, że Python zmienił sposób, w jaki robisz podklasy, więc są na to dwa sposoby i nie mieszają się. Jeśli będziesz mieszać, pojawi się błąd. Przeczytaj ten post, aby zobaczyć różnicę: stackoverflow.com/questions/1713038/…
Mark Lakata
Odpowiedzi:
89
# Initialize using Parent#classMySubClass(MySuperClass):def__init__(self):
MySuperClass.__init__(self)
Lub jeszcze lepiej, użycie wbudowanej funkcji Pythonasuper() (zobacz dokumentację Python 2 / Python 3 ) może być nieco lepszą metodą wywołania rodzica w celu zainicjowania:
# Better initialize using Parent (less redundant).#classMySubClassBetter(MySuperClass):def__init__(self):
super(MySubClassBetter, self).__init__()
Lub dokładnie to samo, co powyżej, z wyjątkiem użycia postaci z zerowym argumentem super(), która działa tylko w definicji klasy:
OTOH, niektórzy ludzie przed nim ostrzegają super, szczególnie w przypadku nowych programistów Pythona (np. Lutz). Unikam tego.
eric
6
Jedynym powodem, którego należy unikać, superjest to, że nie rozumiesz różnic między tym, jak superdziała w Pythonie, a tym, jak super/ parentdziała w innych językach. Wprawdzie nie jest to oczywiste dla osób pochodzących z innych języków, ale nie doszedłbym do wniosku, że kwalifikuje to jako coś, przed czym należy „przestrzec”. To czyni pracę. Po prostu działa inaczej. Po prostu przeczytaj, co tak naprawdę robi w Pythonie, zanim zaczniesz narzekać na wyniki, których się nie spodziewałeś.
classSuperHero(object):#superclass, inherits from default objectdefgetName(self):raise NotImplementedError #you want to override this on the child classesclassSuperMan(SuperHero):#subclass, inherits from SuperHerodefgetName(self):return"Clark Kent"classSuperManII(SuperHero):#another subclassdefgetName(self):return"Clark Kent, Jr."if __name__ == "__main__":
sm = SuperMan()
print sm.getName()
sm2 = SuperManII()
print sm2.getName()
Musisz tylko zdefiniować tę __init__metodę, jeśli chcesz dodać do niej dalszy kod, w przeciwnym razie i tak zostanie użyta oryginalna metoda init (chociaż warto o tym wspomnieć i jest to całkowicie poprawny kod)
dbr
2
Myślę, że pytanie było na tyle niejasne, aby założyć, że może zostać dodany kolejny kod. Lepiej jest podać zbyt wiele informacji niż niewystarczających i zadać kolejne pytanie, gdy program operacyjny je wdroży. :)
Fajne. Właśnie tego szukałem, tj. Podklasy bez rozszerzenia / nadpisań do super.
BuvinJ
9
W powyższych odpowiedziach superjest inicjowany bez żadnych argumentów (słów kluczowych). Często jednak chcesz to zrobić, a także przekazać własne „niestandardowe” argumenty. Oto przykład, który ilustruje ten przypadek użycia:
classSortedList(list):def__init__(self, *args, reverse=False, **kwargs):
super().__init__(*args, **kwargs) # Initialize the super class
self.reverse = reverse
self.sort(reverse=self.reverse) # Do additional things with the custom keyword arguments
Jest to podklasa, listktóra po zainicjowaniu natychmiast sortuje się w kierunku określonym przez reverseargument słowa kluczowego, co ilustrują poniższe testy:
import pytest
deftest_1():assert SortedList([5, 2, 3]) == [2, 3, 5]
deftest_2():
SortedList([5, 2, 3], reverse=True) == [5, 3, 2]
deftest_3():with pytest.raises(TypeError):
sorted_list = SortedList([5, 2, 3], True) # This doesn't work because 'reverse' must be passed as a keyword argumentif __name__ == "__main__":
pytest.main([__file__])
Dzięki przekazaniu *argsdo super, lista może zostać zainicjowana i wypełniona pozycjami, a nie tylko pusta. (Należy pamiętać, że reversejest to argument zawierający tylko słowo kluczowe zgodnie z PEP 3102 ).
Istnieje inny sposób dynamicznego tworzenia podklas w Pythonie za pomocą funkcji type():
SubClass = type('SubClass', (BaseClass,), {'set_x': set_x}) # Methods can be set, including __init__()
Zwykle chcesz używać tej metody podczas pracy z metaklasami. Kiedy chcesz wykonać jakieś automatyzacje niższego poziomu, zmienia to sposób, w jaki Python tworzy klasę. Najprawdopodobniej nigdy nie będziesz musiał tego robić w ten sposób, ale kiedy to zrobisz, będziesz już wiedział, co robisz.
Ta odpowiedź byłaby bardziej pomocna, gdybyś dołączył wyjaśnienie, co robi
grooveplex
4
Chociaż ten kod może pomóc w rozwiązaniu problemu, nie wyjaśnia, dlaczego i / lub jak odpowiada na pytanie. Zapewnienie tego dodatkowego kontekstu znacznie poprawiłoby jego długoterminową wartość edukacyjną. Proszę edytować swoje odpowiedzi, aby dodać wyjaśnienie, w tym, co stosuje się ograniczenia i założenia.
Toby Speight
2
Chociaż ten fragment kodu może rozwiązać problem, dołączenie wyjaśnienia naprawdę pomaga poprawić jakość Twojego posta. Pamiętaj, że odpowiadasz na pytanie do czytelników w przyszłości, a osoby te mogą nie znać powodów, dla których zaproponowałeś kod.
andreas
0
Podklasy w Pythonie są wykonywane w następujący sposób:
Odpowiedzi:
# Initialize using Parent # class MySubClass(MySuperClass): def __init__(self): MySuperClass.__init__(self)
Lub jeszcze lepiej, użycie wbudowanej funkcji Pythona
super()
(zobacz dokumentację Python 2 / Python 3 ) może być nieco lepszą metodą wywołania rodzica w celu zainicjowania:# Better initialize using Parent (less redundant). # class MySubClassBetter(MySuperClass): def __init__(self): super(MySubClassBetter, self).__init__()
Lub dokładnie to samo, co powyżej, z wyjątkiem użycia postaci z zerowym argumentem
super()
, która działa tylko w definicji klasy:class MySubClassBetter(MySuperClass): def __init__(self): super().__init__()
źródło
super
, szczególnie w przypadku nowych programistów Pythona (np. Lutz). Unikam tego.super
jest to, że nie rozumiesz różnic między tym, jaksuper
działa w Pythonie, a tym, jaksuper
/parent
działa w innych językach. Wprawdzie nie jest to oczywiste dla osób pochodzących z innych języków, ale nie doszedłbym do wniosku, że kwalifikuje to jako coś, przed czym należy „przestrzec”. To czyni pracę. Po prostu działa inaczej. Po prostu przeczytaj, co tak naprawdę robi w Pythonie, zanim zaczniesz narzekać na wyniki, których się nie spodziewałeś.Bohaterski mały przykład:
class SuperHero(object): #superclass, inherits from default object def getName(self): raise NotImplementedError #you want to override this on the child classes class SuperMan(SuperHero): #subclass, inherits from SuperHero def getName(self): return "Clark Kent" class SuperManII(SuperHero): #another subclass def getName(self): return "Clark Kent, Jr." if __name__ == "__main__": sm = SuperMan() print sm.getName() sm2 = SuperManII() print sm2.getName()
źródło
class MySubClass(MySuperClass): def __init__(self): MySuperClass.__init__(self) # <the rest of your custom initialization code goes here>
Odcinek od spadków w dokumentacji Pythona wyjaśnia to bardziej szczegółowo
źródło
__init__
metodę, jeśli chcesz dodać do niej dalszy kod, w przeciwnym razie i tak zostanie użyta oryginalna metoda init (chociaż warto o tym wspomnieć i jest to całkowicie poprawny kod)class Class1(object): pass class Class2(Class1): pass
Class2 jest podklasą Class1
źródło
W powyższych odpowiedziach
super
jest inicjowany bez żadnych argumentów (słów kluczowych). Często jednak chcesz to zrobić, a także przekazać własne „niestandardowe” argumenty. Oto przykład, który ilustruje ten przypadek użycia:class SortedList(list): def __init__(self, *args, reverse=False, **kwargs): super().__init__(*args, **kwargs) # Initialize the super class self.reverse = reverse self.sort(reverse=self.reverse) # Do additional things with the custom keyword arguments
Jest to podklasa,
list
która po zainicjowaniu natychmiast sortuje się w kierunku określonym przezreverse
argument słowa kluczowego, co ilustrują poniższe testy:import pytest def test_1(): assert SortedList([5, 2, 3]) == [2, 3, 5] def test_2(): SortedList([5, 2, 3], reverse=True) == [5, 3, 2] def test_3(): with pytest.raises(TypeError): sorted_list = SortedList([5, 2, 3], True) # This doesn't work because 'reverse' must be passed as a keyword argument if __name__ == "__main__": pytest.main([__file__])
Dzięki przekazaniu
*args
dosuper
, lista może zostać zainicjowana i wypełniona pozycjami, a nie tylko pusta. (Należy pamiętać, żereverse
jest to argument zawierający tylko słowo kluczowe zgodnie z PEP 3102 ).źródło
Istnieje inny sposób dynamicznego tworzenia podklas w Pythonie za pomocą funkcji
type()
:SubClass = type('SubClass', (BaseClass,), {'set_x': set_x}) # Methods can be set, including __init__()
Zwykle chcesz używać tej metody podczas pracy z metaklasami. Kiedy chcesz wykonać jakieś automatyzacje niższego poziomu, zmienia to sposób, w jaki Python tworzy klasę. Najprawdopodobniej nigdy nie będziesz musiał tego robić w ten sposób, ale kiedy to zrobisz, będziesz już wiedział, co robisz.
źródło
class Subclass (SuperClass): # Subclass stuff here
źródło
Używasz:
class DerivedClassName(BaseClassName):
Szczegółowe informacje można znaleźć w dokumentacji Pythona, sekcja 9.5 .
źródło
class Mammal(object): #mammal stuff class Dog(Mammal): #doggie stuff
źródło
class BankAccount: def __init__(self, balance=0): self.balance = int(balance) def checkBalance(self): ## Checking opening balance.... return self.balance def deposit(self, deposit_amount=1000): ## takes in cash deposit amount and updates the balance accordingly. self.deposit_amount = deposit_amount self.balance += deposit_amount return self.balance def withdraw(self, withdraw_amount=500): ## takes in cash withdrawal amount and updates the balance accordingly if self.balance < withdraw_amount: ## if amount is greater than balance return `"invalid transaction"` return 'invalid transaction' else: self.balance -= withdraw_amount return self.balance class MinimumBalanceAccount(BankAccount): #subclass MinimumBalanceAccount of the BankAccount class def __init__(self,balance=0, minimum_balance=500): BankAccount.__init__(self, balance=0) self.minimum_balance = minimum_balance self.balance = balance - minimum_balance #print "Subclass MinimumBalanceAccount of the BankAccount class created!" def MinimumBalance(self): return self.minimum_balance c = BankAccount() print(c.deposit(50)) print(c.withdraw(10)) b = MinimumBalanceAccount(100, 50) print(b.deposit(50)) print(b.withdraw(10)) print(b.MinimumBalance())
źródło
Podklasy w Pythonie są wykonywane w następujący sposób:
class WindowElement: def print(self): pass class Button(WindowElement): def print(self): pass
Oto samouczek dotyczący języka Python, który zawiera również klasy i podklasy.
źródło