使用deepcopy时python向变量添加对象

2024-10-02 22:24:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我有几个问题。请记住,我需要使用deepcopy,因为我的类将在复杂性方面不断扩展。你知道吗

  • 当我做深度复制时,有没有办法使它不达到递归限制?你知道吗
  • 当我预生成一个深度副本时,我希望新的副本被附加到NODES变量,就像它在init中所做的那样?你知道吗

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

Tags: nameselfnodeageinitdefcarclass
1条回答
网友
1楼 · 发布于 2024-10-02 22:24:58

首先,你真的应该用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__创建的。由于它是一个类方法,您只需要声明超类名称(顺便说一句,超类是另一种动物,您应该使用不同的名称…)作为类属性。你知道吗

您的代码变成:

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名称即可接受。。。你知道吗

相关问题 更多 >