Python生成器vs理解并通过引用vs值传递 [英] Python generator vs comprehension and pass by reference vs value

查看:100
本文介绍了Python生成器vs理解并通过引用vs值传递的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些代码可以迭代一个字符串,并从该字符串中生成对象列表,这就是我所称的实例.看起来像这样.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆