生成器方法、深拷贝与浅拷贝
我正在尝试在一个自定义类(图类)中避免使用深拷贝(deepcopy)。
这个图类有一些属性,比如顶点、边等等,还有几个生成器方法(带有yield
的函数)。
我需要复制这个图,比如说用H = deepcopy(G)
,但我不想用深拷贝,因为这样会让程序变慢。
那么:
如果我不使用
deepcopy
,那么新图H
中的生成器方法就无法获取图G
中生成器方法的当前状态。如果我不使用生成器方法,而选择使用完整的列表生成器,那么我就会浪费计算时间,做一些没有用的事情。
我的解决方案是尝试对一些特定的生成器方法进行深拷贝,但我遇到了错误。
看起来这些生成器保存了对图G
的顶点和边的引用,然后当我把它们深拷贝到H
时,H
中的生成器仍然引用着G
的属性(这听起来很合理)。
所以,我是不是注定要使用deepcopy
,或者根本不使用生成器方法呢?
有没有第三种更符合Python风格的方法呢?
1 个回答
2
我觉得我明白你想表达的意思。这里有一个简单的例子:
class Graph:
def __init__(self, nodes):
self.nodes = list(nodes)
self.nodegen = self.iternodes()
def iternodes(self):
for node in self.nodes:
yield node
def copy(self):
return Graph(self.nodes)
G = Graph([1, 2, 3, 4])
print G.nodegen.next()
H = G.copy()
print H.nodegen.next()
print G.nodegen.next()
当然,这段代码会打印出 1 1 2
。不过,你希望 H.nodegen
能记住 G.nodegen
的状态,这样当你调用 H.nodegen.next()
时就能打印出 2。一个简单的方法是让它们成为同一个对象:
class Graph:
def __init__(self, nodes, nodegen=None):
self.nodes = list(nodes)
self.nodegen = self.iternodes() if nodegen is None else nodegen
def iternodes(self):
for node in self.nodes:
yield node
def copy(self):
return Graph(self.nodes, self.nodegen)
这样就会打印出 1 2 3
,因为调用 H.nodegen.next()
时也会让 G.nodegen
向前移动。如果这不是你想要的,那么我觉得可以保持一个内部计数器,像这样:
class Graph:
def __init__(self, nodes, jnode=0):
self.nodes = list(nodes)
self.nodegen = self.iternodes()
self.jnode = jnode
def iternodes(self):
while self.jnode < len(self.nodes):
self.jnode += 1
yield self.nodes[self.jnode-1]
def copy(self):
return Graph(self.nodes, self.jnode)
这样会打印出 1 2 2
,我猜这就是你想要的。当然,当你改变 self.nodes
时,你需要处理一些事情,比如使迭代器失效,但我觉得这应该相对简单。