Python 如何获取对对象属性的引用?
我正在寻找一种根据解析到方法的值来改变objects属性的方法。例如:Python 如何获取对对象属性的引用?,python,object,dictionary,attributes,Python,Object,Dictionary,Attributes,我正在寻找一种根据解析到方法的值来改变objects属性的方法。例如: class Character(object): def __init__(self, hp, mp, st, ag): self.hp = hp self.mp = mp self.st = st self.ag = ag def increase_stat(self, stat, value): ''' Increase o
class Character(object):
def __init__(self, hp, mp, st, ag):
self.hp = hp
self.mp = mp
self.st = st
self.ag = ag
def increase_stat(self, stat, value):
''' Increase one of the attributes
(hp, mp, st, ag) by a given value.
'''
stat_dict = {'hp': self.hp,
'mp': self.mp,
'st': self.st,
'ag': self.ag}
stat_attr = stat_dict.get(stat)
# below should be equivalent to self.hp += value
stat_attr += value
hero = Character(hp=10, mp=4, st=3, ag=2)
hero.increase_stat(stat='hp', value=2)
# this should increase the hp by 2
print(hero.hp == 12)
我知道这不起作用,因为stat_dict.get(stat)返回self.hp指向的值,而不是实际的self.hp对象
当前解决方案
我没有将属性作为dict的值,而是使用增加每个stat的方法
class Character(object):
def __init__(self, hp, mp, st, ag):
self.hp = hp
self.mp = mp
self.st = st
self.ag = ag
def increase_stat(self, stat, value):
''' Increase one of the attributes
(hp, mp, st, ag) by a given value.
'''
stat_method_dict = {'hp': self._increase_hp,
'mp': self._increase_mp,
'st': self._increase_st,
'ag': self._increase_ag}
alter_stat_method = stat_method_dict.get(stat)
alter_stat_method(value)
def _increase_hp(self, value):
self.hp += value
def _increase_mp(self, value):
self.mp += value
def _increase_st(self, value):
self.st += value
def _increase_ag(self, value):
self.ag = value
hero = Character(hp=10, mp=4, st=3, ag=2)
hero.increase_stat(stat='hp', value=2)
# this should increase the hp by 2
print(hero.hp == 12)
我的问题是它是重复的,如果我决定向类添加更多属性/统计信息,那么这只会增加重复方法的数量。我想知道是否有一个更好的解决办法,比我已经产生了上述
解决方案
现在看来很明显。谢谢大家
class Character(object):
def __init__(self, hp, mp, st, ag):
self.hp = hp
self.mp = mp
self.st = st
self.ag = ag
def increase_stat(self, stat, value):
''' Increase one of the attributes
(hp, mp, st, ag) by a given value.
'''
current = getattr(self, stat)
setattr(self, stat, current+value)
您可以使用
\uuuu setitem\uuuu
方法来获得更简洁的解决方案:
class Character(object):
def __init__(self, *args):
self.__dict__ = dict(zip(['hp', 'mp', 'st', 'ag'], args))
def __setitem__(self, name, val):
self.__dict__[name] += val
hero = Character(10, 4, 3, 2)
hero['hp'] = 2
print(hero.hp)
输出:
12
12
但是,也可以使用自定义方法实现此策略:
class Character(object):
def __init__(self, *args):
self.__dict__ = dict(zip(['hp', 'mp', 'st', 'ag'], args))
def increase_stat(self, stat, value):
self.__dict__[stat] += value
hero = Character(10, 4, 3, 2)
hero.increase_stat(stat='hp', value=2)
输出:
12
12
你的统计数字真的没用。使用
getattr
和setattr
动态操作属性。比如说:
def increase_stat(self, stat, value):
setattr(self, stat, value + getattr(self, stat))
因此,例如:
In [30]: class Dummy:
...: def __init__(self):
...: self.intelligence = 0
...: self.strength = 10
...: self.hp = 100
...: def increase_stat(self, stat, value):
...: setattr(self, stat, value + getattr(self, stat))
...:
In [31]: d = Dummy()
In [32]: d.strength
Out[32]: 10
In [33]: d.increase_stat('strength', 10)
In [34]: d.strength
Out[34]: 20
也许更容易阅读:
def increase_stat(self, stat, value):
current = getattr(self, stat)
setattr(self, stat, current + value)
注意,这比直接操作实例
\uuu dict\uuu
要好,后者将与属性
对象之类的描述符断开。更不用说没有\uuuuu dict\uuuuu
的对象,例如带有\uuuu插槽的类型使用for循环self.\uuuu dict\uuuu
一种方法是使属性成为可变对象,并公开方法以对其进行变异。。这将与属性对象之类的描述符断开。
-我刚才正在阅读。@wwii任何其他试图设置属性值的尝试也将如此,除非属性对象定义了setter方法。在这种情况下,该代码可以正常工作x.a=y
无论出于何种目的,都与setattr(x,'a',y)
@PaulCornelius一样,但不仅仅如此。即使定义了属性设置器,它也将与\uuuuu dict\uuuu
中断。您必须执行type(obj)。\uuuu dict\uuuuuu[attr]。\uuuu set\uuuuj(obj,value)