【问题标题】:How to increase an object attribute by a variable amount如何通过可变数量增加对象属性
【发布时间】:2018-10-08 10:06:42
【问题描述】:

我在 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,其中朋友是包含这些 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

我不知道为什么。

【问题讨论】:

标签: python class oop


【解决方案1】:

赋值是一个语句,不能在eval 中使用,它只接受表达式。你应该改用exec

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

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

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

【讨论】:

    【解决方案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
    

    【讨论】:

      【解决方案3】:

      明确一点:你知道你可以输入

      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)
      

      【讨论】:

        猜你喜欢
        • 2021-11-24
        • 1970-01-01
        • 2016-03-30
        • 1970-01-01
        • 2014-04-25
        • 2021-05-21
        • 1970-01-01
        • 2014-10-11
        • 1970-01-01
        相关资源
        最近更新 更多