Pythonの:class属性の継承(リスト)
-
21-09-2019 - |
質問
スーパークラスからクラス属性を継承し、後でサブクラスの値を変更すると、罰金を動作します:
class Unit(object):
value = 10
class Archer(Unit):
pass
print Unit.value
print Archer.value
Archer.value = 5
print Unit.value
print Archer.value
出力へのリード線ます。
10
10
10
5
これだけで結構です:アーチャーは、ユニットから値を継承しますが、私はアーチャーの値を変更すると、単位の値がそのまま残っています。
さて、継承された値は、浅いコピー効果のストライキリストである場合や、スーパークラスの値も影響されます:
class Unit(object):
listvalue = [10]
class Archer(Unit):
pass
print Unit.listvalue
print Archer.listvalue
Archer.listvalue[0] = 5
print Unit.listvalue
print Archer.listvalue
出力:
10
10
5
5
は、「ディープコピー」リストに方法はありますか?
感謝
佐野
解決
これは、それが参照および割り当ての問題であり、浅いか深いコピーの問題ではありません。
これは、最初のケースUnit.value
とArcher.value
は同じ値を参照する2つの変数です。あなたがArcher.value = 5
を行うと、あなたはAcher.valueへの新しい参照を割り当てています。
あなたの問題を解決するには、Archer.list
に新しいリスト値を割り当てる必要があります。
は、その後、最も簡単な解決策は、クラスが初期化された割り当てを行うことです。
他のヒント
マイケルの答えはいいと簡単ですが、あなたは、各ユニットサブクラスにその行を追加することを避けるためにしたい場合 - 多分あなたはそのような他のリストの束を持って、メタクラスは、/ <問題を解決する簡単な方法ですP>
class UnitMeta(type):
def __init__(self, *args):
super(UnitMeta, self).__init__(*args)
self.listvalue = [10]
class Unit(object):
__metaclass__ = UnitMeta
pass
class Archer(Unit):
pass
print Unit.listvalue
print Archer.listvalue
Archer.listvalue[0] = 5
print Unit.listvalue
print Archer.listvalue
出力:
[10]
[10]
[10]
[5]
また、
単位で定義されて自動的に検索し、リスト(とdictsを)アップコピーするには、これと同じ考え方を拡張することができますclass UnitMeta(type):
def __init__(self, *args):
super(UnitMeta, self).__init__(*args)
for superclass in self.__mro__:
for k,v in vars(superclass).items():
if isinstance(v, (list, dict, )):
setattr(self, k, type(v)(v))
class Unit(object):
__metaclass__ = UnitMeta
listvalue = [10]
class Archer(Unit):
pass
あなたはアーチャーの定義にリストをコピーできます:
class Archer(Unit):
listvalue = Unit.listvalue[:]
所属していません StackOverflow