Python:多个实例似乎在共享属性(或什么?!)

时间:2012-08-02 03:37:51

标签: python multiple-instances

Python是我的第一语言,我对它很陌生,所以答案可能非常清楚,但经过几个小时的观察和实验,我不确定是什么导致了这个问题。

模块概述: DicePool模块用于管理存储为字典项的“骰子”集合。每个字典键(此处为poolKey)都有一个列表,其中包含有关骰子的一种“类型”的信息,最重要的是,描述其面部的元组和表示“池”中“骰子”类型“x”的数量的整数。

我的具体问题涉及Transfer方法,它曾经是两种方法(基本上是发送和接收),但我认为我可以将它组合成一种方法。当底部的测试代码运行时,我希望它留下dp.dictPool [poolKey] [1] == 0和dp2.dictPool [poolKey] [1] == 2.但是在我做的每一次尝试中,价值观也一样。对不起,我无法更好地对这个问题进行分类。 。 。我真的不知道问题是什么。

无论如何,Transfer方法的一半应该为“sender”实例运行,而一半应该为“receiver”实例运行。

import random

class DicePool(object):

    def __init__(self):
        self.dictPool = {}

    def AddDice(self, poolKey, faces = 6, quant = 1, color = "white"):
        '''faces must be int or items 'a,b,c'; count must be int or def to 1'''
        try: #if count is not an integer, it defaults to 1
            quant = int(quant)
        except:
            print("Quant is not an integer, defaulting to 1")
            quant = 1
        try: #if faces is can be int, a list is built of numbers 1 to faces
            faces = int(faces)
            if faces < 2: #a 1 or 0-sided die breaks the program
                faces = 2
            tempList = []
            for i in range(1, faces+1):
                tempList.append(i)
            faces = tempList
        except: #if faces is not an integer, it is split into list items by ","
            faces = faces.split(",")
        if poolKey in self.dictPool.keys(): #if the key already exists in pool
            self.dictPool[poolKey][1] += quant #add to the quantity, 
        else: #if the key does not already exist, set all attributes
            self.dictPool[poolKey] = [faces, quant, color]

    def Transfer(self, poolKey, targetPool, sendQuant, senderPool = None):
        '''targetPool must be DicePool instance'''
        if targetPool:
            self.dictPool[poolKey][1] -= sendQuant
            targetPool.Transfer(poolKey, None, sendQuant, self)
        else:
            try:
                self.dictPool[poolKey][1] -= sendQuant
            except:
                self.dictPool[poolKey] = senderPool.dictPool[poolKey]
                self.dictPool[poolKey][1] = sendQuant

dp = DicePool()
dp2 = DicePool()

dp.AddDice("d6")
dp.AddDice("d6")
dp.Transfer("d6",dp2,2)
print(dp.dictPool,dp2.dictPool)

4 个答案:

答案 0 :(得分:2)

问题出在这一行:

self.dictPool[poolKey] = senderPool.dictPool[poolKey]

dictPools中的值是列表。在这里,您将一个对象的dictPool值设置为与另一个对象相同的列表。不是列表的副本,而是相同的列表。所以稍后如果你在该列表中添加或减去它,它也会影响另一个,因为它们共享一个列表对象。

尝试self.dictPool[poolKey] = senderPool.dictPool[poolKey][:][:]抓取列表的内容而不是列表对象iself。

答案 1 :(得分:0)

Transfer中的if / else的两个部分中,您将减去数量。你想不想在一个案例中减去它,而是将它添加到另一个案例中吗?

答案 2 :(得分:0)

else: try: self.dictPool[poolKey][1] -= sendQuant应该是+= sendQuant吗?

可能是语义问题,而不是Python语法问题。

答案 3 :(得分:0)

这是Transfer()方法的一个版本,似乎按预期工作(或多或少),虽然看起来非常笨拙:

def Transfer(self, poolKey, targetPool, sendQuant, senderPool = None):
    '''targetPool must be DicePool instance'''
    if isinstance(targetPool, DicePool):
        #valid target, so subtract dice here, then call Transfer on target
        temp = self.dictPool[poolKey][1:2][0] - sendQuant
        print("sent",sendQuant,"leaving",temp)
        targetPool.Transfer(poolKey, "Receiver", sendQuant, self)
    elif targetPool == "Receiver":
        #this executes if a DicePool is named as the targetPool of Transfer
        if poolKey in self.dictPool.keys():
            self.dictPool[poolKey][1:2][0] += sendQuant
        else:
            self.dictPool[poolKey] = senderPool.dictPool[poolKey]
            self.dictPool[poolKey][1:2] = [sendQuant]
        print("now have",self.dictPool[poolKey][1:2][0])
        pass
    else:
        print("Not a valid targetPool, apparently")