简体   繁体   中英

'self' implicit change previous data item in Python iteration

I have a question regarding the usage of self variable in Python. Please look at the following example:

from copy import deepcopy
class IntClass:
    props = {}
    def __init__(self, keys, values):
        indx = 0
        for key in keys:
            self.props[key] = values[indx]
            indx += 1
def display(self):
    for key in self.props.keys():
        print 'key=%s value=%s' %(key,self.props[key])

class IntGen:
    def gen(self, keys, values):
        for vs in values:
            yield [keys, vs]

    def start(self, keys, values):
        self.loader = self.gen(keys, values)

    def nextItem(self):
        return self.loader.next()

keys = ['k1', 'k2', 'k3']
values = [['v1.1', 'v1.2', 'v1.3'], ['v2.1', 'v2.2', 'v2.3'], ['v3.1', 'v3.2', 'v3.3']]

holder = []
intGen = IntGen()
intGen.start(keys, values)
while True:
    try:
        a = intGen.nextItem()
        holder.append(deepcopy(IntClass(a[0],a[1])))
    except StopIteration:
        break

for h in holder:
    h.display()

The result, as in my understanding, should be:

key=k3 value=v3.3
key=k2 value=v3.2
key=k1 value=v3.1
key=k3 value=v2.3
key=k2 value=v2.2
key=k1 value=v2.1
key=k3 value=v1.3
key=k2 value=v1.2
key=k1 value=v1.1

However, what I got is as follows:

key=k3 value=v3.3
key=k2 value=v3.2
key=k1 value=v3.1
key=k3 value=v3.3
key=k2 value=v3.2
key=k1 value=v3.1
key=k3 value=v3.3
key=k2 value=v3.2
key=k1 value=v3.1

It seems to me that within the While loop, when I try to create a new instance of IntClass, that new instance has modified the values stored in props attribute of the instances created in the previous loop , which at the end, cause the holder contains all instances with the same data.

Anyone can point me to the answer? Look like there is something wrong with self variable but I have no glue on how to fix it.

Thanks a lot,

You put the line props = {} directly in the class definition. This will cause all instances of the class to share the same dictionary.

If you want each instance to have its own dictionary, put self.props = {} in __init__ instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM