En Python:
- toutes variables sont des références
- entiers et les chaînes sont immuables
Alors, quand vous faites:
>>> 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
Si vous utilisez un type de données mutable, il fonctionne:
>>> a = []
>>> b = a
>>> b.append(10)
>>> b
[10]
>>> a
[10]
>>> a[0] = 20
>>> b
[20]
Peut-être que vous pouvez créer un conteneur générique:
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())
Ensuite, votre portefeuille peut être une instance de 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
Y ous pouvez définir et/ou récupérer les attributs directement:
>>> wallet.gold
5
>>> wallet.gold += 10
>>> wallet.gold
15
>>> wallet
{'gold': 15, 'silver': 10}
Vous pouvez obtenir l'attribut par nom de l'inventaire ou en utilisant getattr
:
>>> wallet.inventory().get('gold', 0)
15
>>> getattr(wallet, 'gold')
15
Vous pouvez définir par son nom en utilisant dict du paramètre: valeur ou setattr
:
>>> wallet.charge(**{'gold': -10})
{'gold': 5, 'silver': 10}
>>> setattr(wallet, 'gold', 20)
>>> wallet.gold
20
en regardant le résultat, je vois pourquoi en Python j'utilise souvent juste un dictionnaire au lieu de créer une classe - même si je Ne manquez pas la syntaxe de l'objet Javascript où vous pouvez accéder aux propriétés en utilisant soit foo.bar
ou foo["bar"]
.En Python, les structures de données intégrées sont très puissantes et les développeurs Python ont tendance à utiliser une approche «nous sommes tous des adultes consentants» où vous ne faites que transmettre des données sans trop vous soucier de la protection des attributs. Probablement je finirais faire ceci:
>>> wallet = {'gold': 10, 'silver': 15}
Et au lieu d'utiliser une méthode charge(gold=10)
:
>>> wallet['gold'] += 10
Il faut du temps pour ce « il est juste des données » approche de couler, mais après que vous rarement manquent les idiomes plus OO bureaucratiques si communs dans des langages comme Java ou C++ spécialement pour les petits projets/équipes.
Parce que la valeur dans le portefeuille * ne fait pas * référence à l'instance Gold, et les entiers sont immuables. – jonrsharpe
pythontutor.com pourrait vous aider à comprendre cela. Vous ne référencez pas self.gold.amount dans votre dict. Il est copié là-dedans. – UpSampler
C'est un site web très utile. Maintenant, je sais _why_ ça ne marche pas. peut-être des pointeurs dans la façon dont je _do_ référence le self.gold.amount? Merci beaucoup! –