如何从字典中的实例引用变量?
这段代码:
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/