Python:如何引用字典中的变量?

标签 python dictionary

如何从字典中的实例引用变量?

这段代码:

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”语句的完整列表。所以我将本例中包含所有成本(费用)的字典与包含所有实际值的字典结合起来,所以我不必这样做

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())

那么你的钱包就可以是 GenericContainer 的一个实例:

>>> wallet = GenericContainer(gold=10, silver=5)
>>> wallet
{'gold': 10, 'silver': 5}

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

>>> wallet.charge(gold=-20)
ValueError: You don't have enough gold

>>> wallet.gold
5

您可以直接设置和/或检索属性:

>>> wallet.gold
5

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

>>> wallet
{'gold': 15, 'silver': 10}

您可以从 list 中按名称或使用 getattr 获取属性:

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

>>> getattr(wallet, 'gold')
15

您可以使用参数的字典:value 或 setattr 按名称设置它:

>>> 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}

而不是使用 charge(gold=10) 方法:

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

这种“这只是数据”的方法需要时间才能被接受,但之后你就很少会错过在 Java 或 C++ 等语言中常见的官僚 OO 习惯用法,特别是针对小型项目/团队。

关于Python:如何引用字典中的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46760282/

相关文章:

python - Pyramid :获取应用程序绝对 url

python - Python中使用argparse的条件命令行参数

bash - unix map 功能

c# - 可以在 C# 4.0 中创建多类型 lambda 函数的单一多类型集合吗?

python - 用于水平边缘滚动(在 Linux 中)的 Tkinter 事件是什么?

python - 从 Pandas 数据框创建新的动态字典

python - 使用 itertools 将列表拆分为递增序列

python - 字典有列表中的键

python-3.x - 有没有更简单的方法来提取字典的最后一个值?

dictionary - Go 的底层 map