Python生成器vs理解并通过引用vs值传递 [英] Python generator vs comprehension and pass by reference vs value
问题描述
我有一些代码可以迭代一个字符串,并从该字符串中生成对象列表,这就是我所称的实例.看起来像这样.
I have some code that iterates over a string and produces a list of objects from the string, which I'm calling an instance. It looks something like this.
from collections import defaultdict
class MyInstance:
data = defaultdict(str)
def __init__(self, data, parser):
# parse the input
self.parser = parser
class MyParser:
def __init__(self, data):
self.data = data
data = data.split('\n\n')
self.instances = (MyInstance(instance, self) for instance in data)
mydata = # ... coming in from stdin or file
parser = MyParser(mydata)
这很好,但是后来我意识到我需要检查我的实例不止一次.因此,我想我只是将生成器更改为列表理解:
This was working fine, but then I realized I needed to check my instances more than once. So, I figured I would just changed my generator to a list comprehension:
self.instances = [MyInstance(instance, self) for instance in data]
这允许我根据需要多次迭代实例,但是突然之间,所有实例都是相同的.当我在这一行之前打印数据时,每个实例都是唯一的.但是,在理解列表之后,它们都是相同的.
Which allows me to iterate over my instances as many times as a want, but all of a sudden, all of the instances are the same. When I print out the data just before this line, each instance is unique. However, after the list comprehension, they are all the same.
class MyParser:
def __init__(self, data):
self.data = data
data = data.split('\n\n')
print data
self.instances = (MyInstance(instance, self) for instance in data)
print list(self.instances)
打印...
['the soldier sleeps', 'the big soldier sleeps', 'the big wonderful soldier sleeps']
['the big wonderful soldier sleeps', 'the big wonderful soldier sleeps', 'the big wonderful soldier sleeps']
但是,最奇怪的部分是,当我尝试使用与上述类似的代码重新创建此问题时,我无法复制它:
However, the strangest part is that when I tried to recreate this issue using similar code to the above, I couldn't replicate it:
class myClass:
def __init__(self, i):
self.i = i
def __repr__(self):
return self.__str__()
def __str__(self):
return str(self.i)
instances = [myClass(i) for i in range(3)]
print instances
instances = (myClass(i) for i in range(3))
print list(instances)
打印...
[0, 1, 2]
[0, 1, 2]
我检查了每个实例(在破损的代码中)的内存地址是否相同或不同,并且看起来它们是不同的……(尽管我承认我不确定这是否意味着什么)
I checked to see if the memory address of each instance (in the broken code) was the same or different, and it looks like they are different... (though I admit I'm not sure if this means anything)
for i in self.instances:
print id(i) # 4463026760, 4463026544, 4463026616
所以,我不知道发生了什么.关于这些实例为何似乎被链接的任何建议?
So, I have no idea what's going on. Any suggestions of why these instances seem to be linked?
推荐答案
问题似乎与我初始化数据的方式有关.我正在以类的成员身份启动defaultdict:
It seems that the issue has to do with how I was initiating my data. I was initiating a defaultdict as a member of the class:
class myClass:
self.data = defaultdict(str)
def __init__(self, data):
for i, instance in enumerate(data.split('\n')):
# Do something...
self.data[i] = instance
我将其更改为:
class myClass:
def __init__(self, data):
self.data = defaultdict(str)
for i, instance in enumerate(data.split('\n')):
# Do something...
self.data[i] = instance
这解决了我的问题.想知道是否有人知道为什么.
And that fixed my problem. Would be interested to hear if anyone knows why.
这篇关于Python生成器vs理解并通过引用vs值传递的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!