Python:如何在dict中引用变量?

Python:如何在dict中引用变量?,python,dictionary,Python,Dictionary,如何从dict中的实例引用变量 此代码: class Gold(): def __init__(self): self.amount = 10 class Cheese(): def __init__(self, gold): self.gold = gold self.wallet = {'gold' : self.gold.amount} self.charge ={'gold' : 10} def

如何从dict中的实例引用变量

此代码:

class Gold():
    def __init__(self):
        self.amount = 10

class Cheese():
    def __init__(self, gold):
        self.gold = gold
        self.wallet = {'gold' : self.gold.amount}
        self.charge ={'gold' : 10}

    def subtract(self):
        for cat, cost in self.charge.iteritems():
            if self.wallet[cat] >= cost:
                self.wallet[cat] -= cost

gold = Gold()
cheese = Cheese(gold)
cheese.subtract()
print 'gold amount =', cheese.gold.amount, 'wallet =', cheese.wallet
收益率:

gold amount = 10 wallet = {'gold': 0}
而不是

gold amount = 0 wallet = {'gold': 0}
在实际代码中,我不想要一个完整的if语句列表。因此,我将本例中包含所有成本(费用)的dict与包含所有实际值的dict进行耦合,因此我不必这样做

if cost == 'gold':
    pass
if cost == 'action points':
    pass

有什么建议吗? 最后,问题是:

a = 1
b = a
有没有一种方法可以同时更新a和b(b+=1只将b更新为2)

在Python中:

  • 所有变量都是引用
  • 整数和字符串是不可变的
所以当你这样做的时候:

>>> a = 1  # a points to 1
>>> b = a  # b points to 1
>>> b = 10   # b now points to 10, a still points to 1 and 1 is unchanged.
>>> b
10

>>> a
1
如果使用可变数据类型,则它可以工作:

>>> a = []
>>> b = a
>>> b.append(10)
>>> b
[10]

>>> a
[10]

>>> a[0] = 20
>>> b
[20]
也许您可以创建一个通用容器:

class GenericContainer(object):
    def __init__(self, **kwargs):
        self._keys = set()
        for k, v in kwargs.items():
            if k in ('inventory', 'charge'):
                raise ValueError('Unable to override method {}'.format(k))
            setattr(self, k, v)
            self._keys.add(k)

    def charge(self, **kwargs):
        for k, v in kwargs.items():
            if k in ('inventory', 'charge'):
                raise ValueError('Unable to override method {}'.format(k))
            if v < 0 and getattr(self, k, 0) < abs(v):
                raise ValueError("You don't have enough {}".format(k))
            setattr(self, k, getattr(self, k, 0) + v)
            self._keys.add(k)
        return self

    def inventory(self):
        return {k:getattr(self, k) for k in self._keys}

    def __repr__(self):
        return str(self.inventory())
您可以直接设置和/或检索属性:

>>> wallet.gold
5

>>> wallet.gold += 10
>>> wallet.gold
15

>>> wallet
{'gold': 15, 'silver': 10}
您可以从清单中按名称或使用
getattr
获取属性:

>>> wallet.inventory().get('gold', 0)
15

>>> getattr(wallet, 'gold')
15
>>> wallet.charge(**{'gold': -10})
{'gold': 5, 'silver': 10}

>>> setattr(wallet, 'gold', 20)
>>> wallet.gold
20
您可以使用参数dict:value或
setattr
按名称设置它:

>>> wallet.inventory().get('gold', 0)
15

>>> getattr(wallet, 'gold')
15
>>> wallet.charge(**{'gold': -10})
{'gold': 5, 'silver': 10}

>>> setattr(wallet, 'gold', 20)
>>> wallet.gold
20
看看结果,我明白了为什么在Python中我经常使用字典而不是创建类——尽管我确实错过了Javascript对象语法,您可以使用
foo.bar
foo[“bar”]
访问属性

在Python中,内置数据结构非常强大,Python开发人员倾向于使用“我们都是同意的成年人”方法,在这种方法中,您只需传递数据,而不必太在意属性保护。也许我最终会这样做:

>>> wallet = {'gold': 10, 'silver': 15}
而不是使用
充电(gold=10)
方法:

>>> wallet['gold'] += 10

<> P>这是“数据只是”的方法,但你很少错过那些在java或C++语言中特别适用于小型项目/团队的更为官僚化的OO成语。 属性是行为类似于属性的方法。它们是在每次调用时计算的,而不是在创建对象时计算的,并且不再计算。但是,您使用它们的方式相同,因此:

>>> print 'gold amount =', cheese.gold.amount, 'wallet =', cheese.wallet
gold amount = 0 wallet = {'gold': 0}

因为钱包中的值没有引用Gold实例,并且整数是不可变的。pythontutor.com可能会帮助您理解这一点。你的钱包里没有提到self.gold.amount,而是抄写在那里。这是一个非常有用的网站。现在我知道它为什么不起作用了。也许有什么关于我如何引用self.gold.amount的建议?太多了@上取样器不,它不是复制的
wallet['gold']
self.gold.amount
都引用了完全相同的对象,但该对象是不可变的。@LennartWijers我知道了。您是对的,对象是不可变的,但是
wallet['gold']
的内容可以更改。它在这里找到了答案:谢谢!我想我会使用容器类。但我认为问题仍然存在(见编辑)。但是谢谢你花时间帮忙!我花了一些时间才理解你的答案,但它解决了问题。谢谢!你写的代码告诉我:goldamount=10 wallet={'gold':10}。将开始阅读有关属性的内容,尽管这是一个例子。实际代码的行数太多,难以理解names@LennartWijers啊,是的,对不起,您必须在
减法中修改
self.gold
而不是
self.wallet