組み込みのlist
型にいくつかの属性を追加したいので、次のように記述しました。
class MyList(list):
def __new__(cls, *args, **kwargs):
obj = super(MyList, cls).__new__(cls, *args, **kwargs)
obj.append('FirstMen')
return obj
def __init__(self, *args, **kwargs):
self.name = 'Westeros'
def king(self):
print 'IronThrone'
if __name__ == '__main__':
my_list = MyList([1, 2, 3, 4])
print my_list
ただし、my_list
には要素'FirstMen'
のみが含まれます。 __new__
がここで機能しないのはなぜですか?そして、list
のような組み込み型からどのように継承する必要がありますか? str
のような不変型についても同じですか?
list
型は通常、その__init__()
メソッド内でリストの実際の初期化を行います。これは、可変型の規則であるためです。不変の型をサブタイプ化する場合にのみ、__new__()
を上書きする必要があります。リストをサブクラス化するときにcan__new__()
を上書きしますが、ユースケースではそうする意味はあまりありません。 __init__()
を上書きする方が簡単です。
_class MyList(list):
def __init__(self, *args):
list.__init__(self, *args)
self.append('FirstMen')
self.name = 'Westeros'
_
この場合、super()
を使用しないことをお勧めします。ここでlist.__init__()
を呼び出したいが、他には何も呼び出さない。
まず、___new__
_を理解するための演習としてこれを行っていますか?そうでない場合は、あなたがやろうとしていることを行うためのより良い方法がほぼ確実にあります。ここで達成したいことを説明していただけますか?
そうは言っても、あなたの例では次のようになっています。
MyList([1,2,3,4])
を呼び出しますMyList.__new__(MyList,[1,2,3,4])
を呼び出しますlist.__new__(MyList,[1,2,3,4])
を呼び出します。これにより、要素のないMyList
の新しいインスタンスが返されます。 _list.__new__
_はリストに入力されません。それは_list.__init__
_に任せますが、これは決して呼び出されません。__new__
_メソッドは、空のMyList
インスタンスに_'FirstMen'
_を追加します。__new__
_メソッドはMyList
のインスタンスを返します。MyList.__init__([1,2,3,4])
が呼び出されます。name
属性を_'Westeros'
_に設定します。my_list
_に割り当てられ、出力されます。___new__
_の説明については、ここを参照してください: http://docs.python.org/reference/datamodel.html#basic-customization