我试图避免在自定义类(Graph类)中使用deepcopy
图形具有很少的属性,例如顶点,边缘等,以及几种生成器方法(带有yield
的方法)。
我需要复制图表:例如H = deepcopy(G)
但不使用深度复制来加速程序。
然后:
如果我不使用deepcopy
那么
新图H
中的生成器方法
不要得到当前的状态
图G
中的生成器方法。
如果我不使用发电机方法和 选择使用完整列表生成器, 然后我会浪费计算时间 无所事事。
解决方案是尝试deepcopy
某些特定的生成器方法,但是我得到了错误。
似乎发电机保存了对例如G
的顶点和边缘,然后当深度复制到H
时,H
中的生成器仍然引用G
的属性(这听起来合乎逻辑)。
那么,我是否应该使用deepcopy
或者不使用生成器方法?
有第三种pythonic方式吗?
答案 0 :(得分: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
时,你将不得不改变你如何处理迭代器失效之类的事情,但我认为这应该是相当简单的。