Как увеличить атрибут объекта на переменную величину - PullRequest
0 голосов
/ 08 октября 2018

У меня есть класс в Python для фигуры с атрибутами name, здоровья, силы, скрытности, ловкости, оружия и денег.В игре, которую я создаю, есть магазин, чтобы увеличить значение любого целочисленного свойства для определенного элемента.Каждое целочисленное свойство может быть увеличено одним из двух разных предметов с различной стоимостью и силой баффа.Проблема, с которой я столкнулся, заключается в увеличении атрибута на величину и сохранении объекта.

Вот код для объекта:

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 голосов
/ 08 октября 2018

Назначение является оператором и не может использоваться внутри eval, который принимает только выражения.Вы должны использовать exec вместо:

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

Но вместо exec лучше использовать функцию setattr:

setattr(self, attr, getattr(self, attr) + buff)
0 голосов
/ 08 октября 2018

Просто чтобы прояснить: вы знаете, что можете просто набрать

a.foo += 2

Если да, но вам нужен другой метод:

В Python уже есть внутренние функции, которые точно выполняют что вы пытаетесь достичь.Методы называются setattr и getattr.Подробнее о них здесь .А сейчас, как вы можете их использовать:

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)
0 голосов
/ 08 октября 2018

Не используйте 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...