我有几个问题。请记住,我需要使用深层复制,因为我的课程将在复杂性方面进行扩展。
import copy
# Global
NODES = []
# Classes
class Node(object):
def __init__(self, name, age):
self.name = name
self.age = age
class Truck(Node):
def __init__(self, name="", age=0):
super(Truck, self).__init__(name=name, age=age)
NODES.append(self)
class Car(Node):
def __init__(self, name="", age=0):
super(Car, self).__init__(name=name, age=age)
NODES.append(self)
def __deepcopy__(self, memo):
print '__deepcopy__(%s)' % str(memo)
return Car(copy.deepcopy(self, memo))
Truck( name="Tonka Truck")
Truck( name="Monster Truck")
Truck( name="Pickup Truck")
car = Car( name="Oldsmobile Car")
car.age = 55
new_car = copy.deepcopy( car )
type_name = "Car"
cars = [x for x in NODES if type(x).__name__ == type_name]
print cars
print "NODES:"
for node in NODES:
print "\t", node.name, node.age
答案 0 :(得分:2)
首先,你真的应该使用defaultdict
玩具。它只是满足这个要求如果超类不存在,它会添加并附加对象。所以,让我们一起去
Toys = collections.defaultdict(list)
如果您不想使用copy.deepcopy
,只需将Node.__init__
方法更改为:
class Node(object):
def __init__(self, name, superclass):
self.name = name
self.superclass = superclass
Toys[superclass].append(self)
创建新卡车时,它可以正常工作:
t = truck()
Toys['Trucks'][-1] is t
给出了真的
不幸的是,deepcopy
使用了一种特殊的构造方案,并绕过__init__
。
但是__init__
无法做到,只需致电__new__
来帮助......
__new__
是一个较低级别的特殊方法,称为类方法,用于在调用__init__
之前创建对象。即使deepcopy
创建的对象也是使用__new__
创建的。因为它是一个类方法,你只需要声明超类名称(BTW超类是另一种动物而你真的应该使用不同的名称......)作为class attribute。
您的代码变为:
import copy
import collections
# Globals
Toys = collections.defaultdict(list)
class Node(object):
def __new__(cls):
obj = super(Node, cls).__new__(cls)
superclass = cls.superclass
Toys[superclass].append(obj)
return obj
def __init__(self, name=""):
self.name = name
class Truck(Node):
superclass = "Trucks"
class Car(Node):
superclass = "Boats"
class Boat(Node):
superclass = "Nodes"
class Plane(Node):
superclass = "Planes"
t = Truck()
t.name = "Tonka Truck"
print Toys
t2 = copy.deepcopy( t )
print t, t2, Toys
使用此输出:
defaultdict(<type 'list'>, {'Trucks': [<__main__.Truck object at 0x0000000002D71A20>]})
<__main__.Truck object at 0x0000000002D71A20> <__main__.Truck object at 0x0000000002D71B70> defaultdict(<type 'list'>, {'Trucks': [<__main__.Truck object at 0x0000000002D71A20>, <__main__.Truck object at 0x0000000002D71B70>]})
证明:
Trucks
列表已自动添加到Toys
t
创建为Truck()
,已正确添加到Toys['Trucks']
t2
创建deepcopy
已正确添加到Toys['Trucks']
您现在只需更改为superclass
名称即可接受此代码......