如何从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与这个例子中的所有成本(费用)结合到一个带有所有实际值的字典,所以我不必这样做
if cost == 'gold':
pass
if cost == 'action points':
pass
等
有关如何执行此操作的任何提示? 最终的问题是:
a = 1
b = a
有没有办法更新a和b(b + = 1只更新b到2)
答案 0 :(得分:1)
在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}
您可以从广告资源或使用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
或{{1来访问属性}}
在Python中,内置数据结构非常强大,Python开发人员倾向于使用&#34;我们都同意成人&#34;只需传递数据而不必过多关注属性保护的方法。可能我最终会这样做:
foo["bar"]
而不是使用>>> wallet = {'gold': 10, 'silver': 15}
方法:
charge(gold=10)
这需要时间&#34;它只是数据&#34;沉没的方法但在那之后你很少会错过更多官僚主义的OO成语,这些成语在Java或C ++等语言中非常常见,特别适用于小型项目/团队。
答案 1 :(得分:1)
似乎最简单的方法是将wallet
从属性更改为property
。
class Cheese():
def __init__(self, gold):
self.gold = gold
self.charge ={'gold' : 10}
@property
def wallet(self):
return {'gold': self.gold.amount)
def subtract(self):
for cat, cost in self.charge.iteritems():
if self.wallet[cat] >= cost:
self.wallet[cat] -= cost
属性是行为类似属性的方法。它们每次都是在通话时计算,而不是在创建对象时计算,而不是再次计算。但是,你以相同的方式使用它们,所以:
>>> print 'gold amount =', cheese.gold.amount, 'wallet =', cheese.wallet
gold amount = 0 wallet = {'gold': 0}