继承超类的类属性,稍后更改子类的值可以正常工作:
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
这很好:Archer继承了Unit的值,但是当我改变Archer的值时,Unit的值仍然保持不变。
现在,如果继承的值是列表,则浅拷贝效果会发生,超类的值也会受到影响:
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
从超类继承列表时,有没有办法“深度复制”列表?
非常感谢 佐野
答案 0 :(得分:13)
这不是浅层或深层复制的问题,而是引用和分配的问题。
第一种情况Unit.value
和Archer.value
是两个引用相同值的变量。当您执行Archer.value = 5
时,您正在为Acher.value分配新的引用。
要解决您的问题,您需要为Archer.list
分配新的列表值。
如果这些值只能通过类方法访问,那么最简单的解决方案是在初始化类时进行赋值。
答案 1 :(得分:7)
迈克尔的答案很简单,但是如果你想避免将这一行添加到每个单元的子类中 - 也许你有一堆其他的列表,那么元类是一种解决问题的简单方法
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
答案 2 :(得分:0)
您可以复制Archer定义中的列表:
class Archer(Unit):
listvalue = Unit.listvalue[:]