Perhatikan bahwa Python mengubah cara Anda melakukan subclass, jadi ada 2 cara untuk melakukannya, dan mereka tidak dapat bercampur. Anda akan mendapatkan pesan kesalahan jika mencampur. Baca posting ini untuk melihat perbedaannya: stackoverflow.com/questions/1713038/…
Mark Lakata
Jawaban:
90
# Initialize using Parent#classMySubClass(MySuperClass):def__init__(self):
MySuperClass.__init__(self)
Atau, lebih baik lagi, penggunaan fungsi bawaan Python , super()(lihat dokumentasi Python 2 / Python 3 untuk itu) mungkin merupakan metode yang sedikit lebih baik untuk memanggil induk untuk inisialisasi:
# Better initialize using Parent (less redundant).#classMySubClassBetter(MySuperClass):def__init__(self):super(MySubClassBetter, self).__init__()
Atau, sama persis seperti di atas, kecuali menggunakan bentuk argumen nol super(), yang hanya berfungsi di dalam definisi kelas:
OTOH, beberapa orang berhati-hati super, terutama untuk programmer Python baru (mis., Lutz). Saya menghindarinya.
eric
7
Satu-satunya alasan untuk menghindarinya superadalah jika Anda tidak memahami perbedaan antara cara superkerja Python, dan cara super/ parentkerja dalam bahasa lain. Memang ini tidak jelas bagi orang-orang yang berasal dari bahasa lain, tetapi saya tidak akan menyimpulkan bahwa hal itu memenuhi syarat sebagai sesuatu yang harus "diwaspadai". Ini tidak bekerja. Ini hanya bekerja secara berbeda. Baca saja tentang apa yang sebenarnya dilakukannya dengan Python sebelum Anda mengeluh tentang mendapatkan hasil yang tidak Anda harapkan.
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()
Anda hanya perlu mendefinisikan __init__metode itu jika ingin menambahkan kode lebih lanjut, jika tidak metode init asli tetap digunakan (meskipun perlu disebutkan, dan merupakan kode yang benar-benar valid)
dbr
2
Saya pikir pertanyaan itu cukup samar untuk mengasumsikan mungkin ada kode lebih lanjut yang ditambahkan. Lebih baik memberikan terlalu banyak info daripada tidak cukup dan berakhir dengan pertanyaan lain saat OP mengimplementasikannya. :)
Keren. Inilah yang sebenarnya saya cari, yaitu sub kelas tanpa ekstensi / menimpa super.
BuvinJ
10
Dalam jawaban di atas, superini diinisialisasi tanpa argumen (kata kunci). Namun, sering kali Anda ingin melakukan itu, serta menyampaikan beberapa argumen 'kebiasaan' Anda sendiri. Berikut adalah contoh yang menggambarkan kasus penggunaan ini:
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
Ini adalah subkelas listyang, ketika diinisialisasi, langsung mengurutkan dirinya sendiri ke arah yang ditentukan oleh reverseargumen kata kunci, seperti yang diilustrasikan oleh pengujian berikut:
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__])
Berkat penerusan *argske super, daftar dapat diinisialisasi dan diisi dengan item, bukan hanya kosong. (Perhatikan bahwa reverseargumen hanya kata kunci sesuai dengan PEP 3102 ).
Ada cara lain untuk membuat subclass di python secara dinamis dengan fungsi type():
SubClass = type('SubClass', (BaseClass,), {'set_x': set_x}) # Methods can be set, including __init__()
Anda biasanya ingin menggunakan metode ini saat bekerja dengan metaclasses. Ketika Anda ingin melakukan otomatisasi tingkat yang lebih rendah, itu mengubah cara python membuat kelas. Kemungkinan besar Anda tidak perlu melakukannya dengan cara ini, tetapi ketika Anda melakukannya, Anda sudah akan tahu apa yang Anda lakukan.
Jawaban ini akan lebih membantu jika Anda menyertakan penjelasan tentang fungsinya
grooveplex
4
Meskipun kode ini dapat membantu memecahkan masalah, kode ini tidak menjelaskan mengapa dan / atau bagaimana menjawab pertanyaan tersebut. Memberikan konteks tambahan ini secara signifikan akan meningkatkan nilai pendidikan jangka panjangnya. Harap edit jawaban Anda untuk menambahkan penjelasan, termasuk batasan dan asumsi apa yang berlaku.
Toby Speight
2
Meskipun cuplikan kode ini dapat menyelesaikan pertanyaan, menyertakan penjelasan sangat membantu meningkatkan kualitas posting Anda. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa mendatang, dan orang-orang itu mungkin tidak tahu alasan saran kode Anda.
andreas
0
Subclassing dengan Python dilakukan sebagai berikut:
Jawaban:
# Initialize using Parent # class MySubClass(MySuperClass): def __init__(self): MySuperClass.__init__(self)
Atau, lebih baik lagi, penggunaan fungsi bawaan Python ,
super()
(lihat dokumentasi Python 2 / Python 3 untuk itu) mungkin merupakan metode yang sedikit lebih baik untuk memanggil induk untuk inisialisasi:# Better initialize using Parent (less redundant). # class MySubClassBetter(MySuperClass): def __init__(self): super(MySubClassBetter, self).__init__()
Atau, sama persis seperti di atas, kecuali menggunakan bentuk argumen nol
super()
, yang hanya berfungsi di dalam definisi kelas:class MySubClassBetter(MySuperClass): def __init__(self): super().__init__()
sumber
super
, terutama untuk programmer Python baru (mis., Lutz). Saya menghindarinya.super
adalah jika Anda tidak memahami perbedaan antara carasuper
kerja Python, dan carasuper
/parent
kerja dalam bahasa lain. Memang ini tidak jelas bagi orang-orang yang berasal dari bahasa lain, tetapi saya tidak akan menyimpulkan bahwa hal itu memenuhi syarat sebagai sesuatu yang harus "diwaspadai". Ini tidak bekerja. Ini hanya bekerja secara berbeda. Baca saja tentang apa yang sebenarnya dilakukannya dengan Python sebelum Anda mengeluh tentang mendapatkan hasil yang tidak Anda harapkan.Contoh kecil heroik:
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()
sumber
class MySubClass(MySuperClass): def __init__(self): MySuperClass.__init__(self) # <the rest of your custom initialization code goes here>
The bagian tentang warisan dalam dokumentasi python menjelaskan hal itu secara lebih rinci
sumber
__init__
metode itu jika ingin menambahkan kode lebih lanjut, jika tidak metode init asli tetap digunakan (meskipun perlu disebutkan, dan merupakan kode yang benar-benar valid)class Class1(object): pass class Class2(Class1): pass
Kelas2 adalah sub-kelas dari Kelas1
sumber
Dalam jawaban di atas,
super
ini diinisialisasi tanpa argumen (kata kunci). Namun, sering kali Anda ingin melakukan itu, serta menyampaikan beberapa argumen 'kebiasaan' Anda sendiri. Berikut adalah contoh yang menggambarkan kasus penggunaan ini: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
Ini adalah subkelas
list
yang, ketika diinisialisasi, langsung mengurutkan dirinya sendiri ke arah yang ditentukan olehreverse
argumen kata kunci, seperti yang diilustrasikan oleh pengujian berikut: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__])
Berkat penerusan
*args
kesuper
, daftar dapat diinisialisasi dan diisi dengan item, bukan hanya kosong. (Perhatikan bahwareverse
argumen hanya kata kunci sesuai dengan PEP 3102 ).sumber
Ada cara lain untuk membuat subclass di python secara dinamis dengan fungsi
type()
:SubClass = type('SubClass', (BaseClass,), {'set_x': set_x}) # Methods can be set, including __init__()
Anda biasanya ingin menggunakan metode ini saat bekerja dengan metaclasses. Ketika Anda ingin melakukan otomatisasi tingkat yang lebih rendah, itu mengubah cara python membuat kelas. Kemungkinan besar Anda tidak perlu melakukannya dengan cara ini, tetapi ketika Anda melakukannya, Anda sudah akan tahu apa yang Anda lakukan.
sumber
class Subclass (SuperClass): # Subclass stuff here
sumber
Kau gunakan:
class DerivedClassName(BaseClassName):
Untuk detailnya, lihat dokumen Python, bagian 9.5 .
sumber
class Mammal(object): #mammal stuff class Dog(Mammal): #doggie stuff
sumber
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())
sumber
Subclassing dengan Python dilakukan sebagai berikut:
class WindowElement: def print(self): pass class Button(WindowElement): def print(self): pass
Berikut adalah tutorial tentang Python yang juga berisi kelas dan subclass.
sumber