我在python中有一个关于人物的类,该人物具有名称,健康,力量,隐身性,敏捷性,武器和金钱。我正在游戏中开设一家商店,以通过特定项目来增加任何整数属性的值。每个整数属性可以增加两个不同项目之一,以增加成本和增强强度。我遇到的问题实际上是按数量增加属性并保存对象。
这是对象的代码:
class Figure:
def __init__(self, stats):
#create figure object
self.name = stats[0]
self.health = int(stats[1])
self.strength = int(stats[2])
self.stealth = int(stats[3])
self.agility = int(stats[4])
self.weapons = int(stats[5])
self.money = int(stats[6])
def show_person(self):
#show object attributes
print("\n\n{}\n\nHealth: {}\nStrength: {}\nStealth: {}\nCunning: {}\nWeapons: {}\nMoney: £{}".format(self.name.title(),self.health,self.strength,self.stealth,self.cunning,self.weapons, self.money))
def set_attr(self,attr,buff):
#increase character attribute by a variable amount
eval("self.{} = self.{} + {}".format(attr,attr,buff))
我可能会使用friend.set_attr("stealth",10)
将朋友的隐身值提高10,其中friend是包含以下Figure对象之一的变量,但会引发此错误:
File Computer Science\python\oop game.py", line 21, in set_attr
exec(eval("self.{} = self.{} + {}".format(attr,attr,buff)))
File "<string>", line 1
self.agility = self.agility + 4
^
SyntaxError: invalid syntax
我不知道为什么。
答案 0 :(得分:4)
赋值是一个语句,不能在仅接受表达式的eval
内部使用。您应该改用exec
:
exec("self.{} = self.{} + {}".format(attr,attr,buff))
但是最好使用exec
函数,而不要使用setattr
:
setattr(self, attr, getattr(self, attr) + buff)
答案 1 :(得分:2)
请勿使用exec
和eval
。使用getattr
和setattr
:
class Foo:
def __init__(self):
self.x = 0
def set_attr(self, attr, buff):
new_val = getattr(self, attr) + buff
setattr(self, attr, new_val)
foo = Foo()
foo.set_attr('x', 10)
print(foo.x)
# 10
foo.set_attr('x', 11)
print(foo.x)
# 21
或者可以使用vars
直接修改属性(我个人不太喜欢):
class Foo:
def __init__(self):
self.x = 0
def set_attr(self, attr, buff):
vars(self)[attr] += buff
foo = Foo()
foo.set_attr('x', 10)
print(foo.x)
# 10
foo.set_attr('x', 11)
print(foo.x)
# 21
答案 2 :(得分:1)
请明确说明:您知道您可以键入
a.foo += 2
如果是,但是您需要其他方法:
Python已经具有可以准确实现您想要实现的功能的内部函数。
这些方法称为setattr
和getattr
。详细了解它们here。现在,这是如何使用它们:
class A:
b = 3
a = A()
setattr(a, 'b', 5)
print(a.b) # 5
print(getattr(a, 'b')) # 5
setattr(a, 'b', getattr(a, 'b') + 5)
print(a.b) # 10
因此,您可以实现一种增加属性的方法,如下所示:
class A:
def incr_attr(self, attr_name, amount):
setattr(self, attr_name, getattr(self, attr_name) + amount)
或者,更加方便:
def incr_attrs(self, **attr_map):
for attr_name, amount in attr_map.items():
setattr(self, attr_name, getattr(self, attr_name) + amount)
因此您可以输入
A.incr_attr(stealth=3, money=10)