Python:如何在dict中引用变量?
如何从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
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