Observe que o Python mudou a maneira como você faz subclasses, portanto, existem 2 maneiras de fazer isso, e elas não se misturam. Você obterá um erro se misturar. Leia esta postagem para ver a diferença: stackoverflow.com/questions/1713038/…
Mark Lakata
Respostas:
89
# Initialize using Parent#classMySubClass(MySuperClass):def__init__(self):
MySuperClass.__init__(self)
Ou, melhor ainda, o uso da função integrada do Python super()(consulte a documentação do Python 2 / Python 3 para isso) pode ser um método um pouco melhor de chamar o pai para inicialização:
# Better initialize using Parent (less redundant).#classMySubClassBetter(MySuperClass):def__init__(self):
super(MySubClassBetter, self).__init__()
Ou exatamente a mesma coisa acima, exceto usando a forma de argumento zero de super(), que só funciona dentro de uma definição de classe:
OTOH, algumas pessoas alertam contra super, especialmente para novos programadores Python (por exemplo, Lutz). Eu evito isso.
Eric
6
A única razão para evitar superé se você não entende as diferenças entre como superfunciona em Python e como super/ parentfunciona em outras linguagens. Reconheço que isso não é óbvio para pessoas que vêm de outras línguas, mas eu não concluiria que isso o qualifique como algo a "prevenir". Ele faz o trabalho. Simplesmente funciona de forma diferente. Apenas leia sobre o que ele realmente faz em Python antes de reclamar sobre a obtenção de resultados inesperados.
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()
Você só precisa definir esse __init__método se quiser adicionar mais código a ele, caso contrário, o método init original será usado de qualquer maneira (embora valha a pena mencionar, e é um código perfeitamente válido)
dbr
2
Acho que a pergunta foi vaga o suficiente para assumir que pode haver mais código adicionado. Melhor fornecer muitas informações do que não o suficiente e acabar com outra pergunta quando o OP implementa. :)
Legal. Isso é o que eu estava procurando, ou seja, uma subclasse sem extensão / substitui o super.
BuvinJ
9
Nas respostas acima, o superé inicializado sem nenhum argumento (palavra-chave). Freqüentemente, entretanto, você gostaria de fazer isso, bem como transmitir alguns argumentos 'personalizados' de sua preferência. Aqui está um exemplo que ilustra este caso de uso:
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
Esta é uma subclasse da listqual, quando inicializada, imediatamente se classifica na direção especificada pelo reverseargumento de palavra - chave, como os seguintes testes ilustram:
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__])
Graças à transmissão de *argspara super, a lista pode ser inicializada e preenchida com itens em vez de ficar apenas vazia. (Observe que reverseé um argumento apenas de palavra-chave de acordo com PEP 3102 ).
Há outra maneira de criar subclasses em python dinamicamente com uma função type():
SubClass = type('SubClass', (BaseClass,), {'set_x': set_x}) # Methods can be set, including __init__()
Você geralmente deseja usar este método ao trabalhar com metaclasses. Quando você deseja fazer algumas automações de nível inferior, isso altera a maneira como o python cria classes. Provavelmente, você nunca precisará fazer dessa maneira, mas quando o fizer, já saberá o que está fazendo.
Esta resposta seria mais útil se você incluísse uma explicação do que ele faz
grooveplex
4
Embora este código possa ajudar a resolver o problema, ele não explica por que e / ou como responde à pergunta. Fornecer esse contexto adicional melhoraria significativamente seu valor educacional a longo prazo. Por favor edite sua resposta para adicionar explicação, incluindo o que limitações e premissas se aplicam.
Toby Speight de
2
Embora este snippet de código possa resolver a questão, incluir uma explicação realmente ajuda a melhorar a qualidade de sua postagem. Lembre-se de que você responderá à pergunta para leitores no futuro, e essas pessoas podem não saber os motivos de sua sugestão de código.
andreas de
0
A criação de subclasses em Python é feita da seguinte maneira:
Respostas:
# Initialize using Parent # class MySubClass(MySuperClass): def __init__(self): MySuperClass.__init__(self)
Ou, melhor ainda, o uso da função integrada do Python
super()
(consulte a documentação do Python 2 / Python 3 para isso) pode ser um método um pouco melhor de chamar o pai para inicialização:# Better initialize using Parent (less redundant). # class MySubClassBetter(MySuperClass): def __init__(self): super(MySubClassBetter, self).__init__()
Ou exatamente a mesma coisa acima, exceto usando a forma de argumento zero de
super()
, que só funciona dentro de uma definição de classe:class MySubClassBetter(MySuperClass): def __init__(self): super().__init__()
fonte
super
, especialmente para novos programadores Python (por exemplo, Lutz). Eu evito isso.super
é se você não entende as diferenças entre comosuper
funciona em Python e comosuper
/parent
funciona em outras linguagens. Reconheço que isso não é óbvio para pessoas que vêm de outras línguas, mas eu não concluiria que isso o qualifique como algo a "prevenir". Ele faz o trabalho. Simplesmente funciona de forma diferente. Apenas leia sobre o que ele realmente faz em Python antes de reclamar sobre a obtenção de resultados inesperados.Um pequeno exemplo heróico:
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()
fonte
class MySubClass(MySuperClass): def __init__(self): MySuperClass.__init__(self) # <the rest of your custom initialization code goes here>
A seção sobre herança na documentação do python explica em mais detalhes
fonte
__init__
método se quiser adicionar mais código a ele, caso contrário, o método init original será usado de qualquer maneira (embora valha a pena mencionar, e é um código perfeitamente válido)class Class1(object): pass class Class2(Class1): pass
Class2 é uma subclasse de Class1
fonte
Nas respostas acima, o
super
é inicializado sem nenhum argumento (palavra-chave). Freqüentemente, entretanto, você gostaria de fazer isso, bem como transmitir alguns argumentos 'personalizados' de sua preferência. Aqui está um exemplo que ilustra este caso de uso: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
Esta é uma subclasse da
list
qual, quando inicializada, imediatamente se classifica na direção especificada peloreverse
argumento de palavra - chave, como os seguintes testes ilustram: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__])
Graças à transmissão de
*args
parasuper
, a lista pode ser inicializada e preenchida com itens em vez de ficar apenas vazia. (Observe quereverse
é um argumento apenas de palavra-chave de acordo com PEP 3102 ).fonte
Há outra maneira de criar subclasses em python dinamicamente com uma função
type()
:SubClass = type('SubClass', (BaseClass,), {'set_x': set_x}) # Methods can be set, including __init__()
Você geralmente deseja usar este método ao trabalhar com metaclasses. Quando você deseja fazer algumas automações de nível inferior, isso altera a maneira como o python cria classes. Provavelmente, você nunca precisará fazer dessa maneira, mas quando o fizer, já saberá o que está fazendo.
fonte
class Subclass (SuperClass): # Subclass stuff here
fonte
Você usa:
class DerivedClassName(BaseClassName):
Para obter detalhes, consulte a documentação do Python, seção 9.5 .
fonte
class Mammal(object): #mammal stuff class Dog(Mammal): #doggie stuff
fonte
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())
fonte
A criação de subclasses em Python é feita da seguinte maneira:
class WindowElement: def print(self): pass class Button(WindowElement): def print(self): pass
Aqui está um tutorial sobre Python que também contém classes e subclasses.
fonte