如何将对象属性增加可变数量

时间:2018-10-08 10:06:43

标签: python class oop

我在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

我不知道为什么。

3 个答案:

答案 0 :(得分:4)

赋值是一个语句,不能在仅接受表达式的eval内部使用。您应该改用exec

exec("self.{} = self.{} + {}".format(attr,attr,buff))

但是最好使用exec函数,而不要使用setattr

setattr(self, attr, getattr(self, attr) + buff)

答案 1 :(得分:2)

请勿使用execeval。使用getattrsetattr

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已经具有可以准确实现您想要实现的功能的内部函数。 这些方法称为setattrgetattr。详细了解它们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)