もともと私は この質問 を聞きたかったのですが、それからそれはすでに考えられていたことがわかりました...
あちこち探して extending configparser のこの例を見つけました。以下はPython 3で動作します:
$ python3
Python 3.2.3rc2 (default, Mar 21 2012, 06:59:51)
[GCC 4.6.3] on linux2
>>> from configparser import SafeConfigParser
>>> class AmritaConfigParser(SafeConfigParser):
... def __init_(self):
... super().__init__()
...
>>> cfg = AmritaConfigParser()
しかし、Python 2ではそうではありません:
>>> class AmritaConfigParser(SafeConfigParser):
... def __init__(self):
... super(SafeConfigParser).init()
...
>>> cfg = AmritaConfigParser()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __init__
TypeError: must be type, not classob
その後、Python New Class vs. Old Classスタイルを少し読みます(例 here 。
class MyConfigParser(ConfigParser.ConfigParser):
def Write(self, fp):
"""override the module's original write funcition"""
....
def MyWrite(self, fp):
"""Define new function and inherit all others"""
しかし、initを呼び出すべきではありませんか?これはPython 2に相当しますか:
class AmritaConfigParser(ConfigParser.SafeConfigParser):
#def __init__(self):
# super().__init__() # Python3 syntax, or rather, new style class syntax ...
#
# is this the equivalent of the above ?
def __init__(self):
ConfigParser.SafeConfigParser.__init__(self)
super()
(引数なし)はPython 3で導入されました(__class__
とともに):
super() -> same as super(__class__, self)
したがって、新しいスタイルのクラスのPython 2と同等になります。
super(CurrentClass, self)
古いスタイルのクラスでは、常に使用できます:
class Classname(OldStyleParent):
def __init__(self, *args, **kwargs):
OldStyleParent.__init__(self, *args, **kwargs)
単一継承の場合(1つのクラスのみをサブクラス化する場合)、新しいクラスは基本クラスのメソッドを継承します。これには__init__
が含まれます。したがって、クラスで定義しない場合は、ベースから取得します。
複数の継承(一度に複数のクラスをサブクラス化)を導入すると、事態は複雑になります。これは、複数の基本クラスに__init__
がある場合、クラスは最初のクラスのみを継承するためです。
このような場合、可能であればsuper
を使用する必要があります。その理由を説明します。しかし、常にできるとは限りません。問題は、すべての基本クラスもそれを使用しなければならないことです(そしてその基本クラスもツリー全体)。
その場合は、これも正常に機能します(Python 3で、Python 2に作り直すことができます-super
もあります)。
class A:
def __init__(self):
print('A')
super().__init__()
class B:
def __init__(self):
print('B')
super().__init__()
class C(A, B):
pass
C()
#prints:
#A
#B
独自の基本クラスがなくても、両方の基本クラスがsuper
を使用する方法に注目してください。
super
は、MROの次のクラスからメソッドを呼び出します(メソッド解決順序)。 C
のMROは、(C, A, B, object)
です。 C.__mro__
を印刷して確認できます。
したがって、C
はA
から__init__
を継承し、A.__init__
のsuper
はB.__init__
を呼び出します(B
はMROのA
に続きます)。
したがって、C
で何もしないと、両方を呼び出すことになります。
super
を使用していない場合、(以前と同様に)A.__init__
を継承することになりますが、今回はB.__init__
を呼び出すものは何もありません。
class A:
def __init__(self):
print('A')
class B:
def __init__(self):
print('B')
class C(A, B):
pass
C()
#prints:
#A
これを修正するには、C.__init__
を定義する必要があります:
class C(A, B):
def __init__(self):
A.__init__(self)
B.__init__(self)
それに関する問題は、より複雑なMIツリーでは、一部のクラスの__init__
メソッドが複数回呼び出されることがありますが、super/MROはそれらが一度だけ呼び出されることを保証することです。
要するに、それらは同等です。履歴ビューを見てみましょう:
(1)最初は、関数は次のようになります。
class MySubClass(MySuperClass):
def __init__(self):
MySuperClass.__init__(self)
(2)コードをより抽象的な(そしてより移植性の高い)にする。スーパークラスを取得する一般的な方法は、次のように考案されています。
super(<class>, <instance>)
また、init関数には次のものがあります。
class MySubClassBetter(MySuperClass):
def __init__(self):
super(MySubClassBetter, self).__init__()
ただし、クラスとインスタンスの両方を明示的に渡す必要があると、DRY(自分自身を繰り返さないでください)規則に少し違反します。
(3)V3。よりスマートです
super()
ほとんどの場合で十分です。 http://www.python.org/dev/peps/pep-3135/ を参照できます
Python 3の簡単で完全な例がありますが、ほとんどの人が現在使用しているようです。
class MySuper(object):
def __init__(self,a):
self.a = a
class MySub(MySuper):
def __init__(self,a,b):
self.b = b
super().__init__(a)
my_sub = MySub(42,'chickenman')
print(my_sub.a)
print(my_sub.b)
与える
42
chickenman
Super()での抽象クラスの使用を含む別のpython3実装。あなたはそれを覚えておくべきです
super().init(name、10)
と同じ効果があります
Person .init(self、name、10)
Super()には隠された「自己」があるので、同じオブジェクトがスーパークラスのinitメソッドに渡され、それを呼び出したオブジェクトに属性が追加されることに注意してください。したがって、super()
getsはPerson
に変換され、非表示のselfを含めると、上記のコードフラグメントが取得されます。
from abc import ABCMeta, abstractmethod
class Person(metaclass=ABCMeta):
name = ""
age = 0
def __init__(self, personName, personAge):
self.name = personName
self.age = personAge
@abstractmethod
def showName(self):
pass
@abstractmethod
def showAge(self):
pass
class Man(Person):
def __init__(self, name, height):
self.height = height
# Person.__init__(self, name, 10)
super().__init__(name, 10) # same as Person.__init__(self, name, 10)
# basically used to call the superclass init . This is used incase you want to call subclass init
# and then also call superclass's init.
# Since there's a hidden self in the super's parameters, when it's is called,
# the superclasses attributes are a part of the same object that was sent out in the super() method
def showIdentity(self):
return self.name, self.age, self.height
def showName(self):
pass
def showAge(self):
pass
a = Man("piyush", "179")
print(a.showIdentity())