使用exec修改类中的全局变量

发布于 2025-01-12 13:07:01 字数 2958 浏览 2 评论 0原文

我最近正在重构一些代码以使用 OOP,并且遇到了一个问题,我无法完全获取全局变量、exec() 或两者的组合去工作。相关代码如下:

# invObject class. Has all properties of an inventory object.
class invObject:
    def __init__(self, name, info, output, effect):
        self.name = name # Used in menus.
        self.info = info # Describes effect.
        self.output = output # Printed on use.
        self.effect = effect # Executed on use.

    def printInfo(self): # Function for name and description.
        return "{} - {}".format(self.name, self.info)

    def use(self): # Function to use items. It's that easy.
        global dodgeChance
        global maxHp
        global hp
        global atk
        exec(self.effect)
        print(self.output) # Prints output. Also very simple.
        print("{} {} {} {}".format(dodgeChance, maxHp, hp, atk)) # debugging
...

inventory[slot].use() # does not update values

基本概要:inventory[slot].use() 应调用对象的use() 函数。 use() 应该执行存储在 inventory[slot].effect 中的代码。

调试行的输出不会改变任何内容,即使在函数内部也是如此。我已经尝试过使其 return exec(self.effect) 无济于事。 print(self.output) 确实有效。

编辑:这是一个最小的可重现示例,其中包括运行所需的所有内容,而不仅仅是最重要的内容。

# Assign base stats
dodgeChance = 0
maxHp = int(input("Input maximum HP. > "))
hp = int(input("Input current HP. > "))

# invObject class. Has all properties of an inventory object.
class invObject:
    def __init__(self, name, info, output, effect):
        self.name = name # Used in menus.
        self.info = info # Describes effect.
        self.output = output # Printed on use.
        self.effect = effect # Executed on use.

    def printInfo(self): # Function for name and description.
        return "{} - {}".format(self.name, self.info)

    def use(self): # Function to use items. It's that easy.
        global dodgeChance
        global maxHp
        global hp
        global atk
        exec(self.effect)
        print(self.output) # Prints output. Also very simple.
        print("{} {} {} {}".format(dodgeChance, maxHp, hp, atk)) # debugging

empty = invObject("None", "Vacant slot.", "There's nothing in that slot!", "")
apple = invObject("Apple", "Gives 20 health.", "Ate the apple. Gained 20 health.", "hp = hp + 20\nif hp > maxHp: hp = maxHp")
drink = invObject("Drink", "Some kind of energy drink. Raises dodge chance to 75%.", "Drank the drink. Dodge chance is now 75%!", "dodgeChance = 75")

# Assign base inventory
inventory = [apple, drink, empty]

slot = int(input("Input slot number to use. ")) - 1
inventory[slot].use() # does not update values

# Show final stats
print("New HP value: " + str(hp))
print("Dodge chance: " + str(dodgeChance) + "%")
print()
print("Inventory contents:")
print("Slot 1: " + str(inventory[0].name))
print("Slot 2: " + str(inventory[1].name))
print("Slot 3: " + str(inventory[2].name))

编辑2:另一件事:如果我不使用exec(),代码就可以工作(例如,将其更改为hp += 20)。

I've recently been refactoring some of my code to use OOP, and I've run into a problem where I can't quite get either global vars, exec(), or a combination of the two to work. The relevant code is below:

# invObject class. Has all properties of an inventory object.
class invObject:
    def __init__(self, name, info, output, effect):
        self.name = name # Used in menus.
        self.info = info # Describes effect.
        self.output = output # Printed on use.
        self.effect = effect # Executed on use.

    def printInfo(self): # Function for name and description.
        return "{} - {}".format(self.name, self.info)

    def use(self): # Function to use items. It's that easy.
        global dodgeChance
        global maxHp
        global hp
        global atk
        exec(self.effect)
        print(self.output) # Prints output. Also very simple.
        print("{} {} {} {}".format(dodgeChance, maxHp, hp, atk)) # debugging
...

inventory[slot].use() # does not update values

Basic rundown: inventory[slot].use() should call the use() function of the object. use() should execute the code stored in inventory[slot].effect.

The output from the debugging line doesn't change anything, even inside the function. I've already tried making it return exec(self.effect) to no avail. print(self.output) does work.

EDIT: Here's a minimal reproducible example that includes everything it needs to run, not just the most important things.

# Assign base stats
dodgeChance = 0
maxHp = int(input("Input maximum HP. > "))
hp = int(input("Input current HP. > "))

# invObject class. Has all properties of an inventory object.
class invObject:
    def __init__(self, name, info, output, effect):
        self.name = name # Used in menus.
        self.info = info # Describes effect.
        self.output = output # Printed on use.
        self.effect = effect # Executed on use.

    def printInfo(self): # Function for name and description.
        return "{} - {}".format(self.name, self.info)

    def use(self): # Function to use items. It's that easy.
        global dodgeChance
        global maxHp
        global hp
        global atk
        exec(self.effect)
        print(self.output) # Prints output. Also very simple.
        print("{} {} {} {}".format(dodgeChance, maxHp, hp, atk)) # debugging

empty = invObject("None", "Vacant slot.", "There's nothing in that slot!", "")
apple = invObject("Apple", "Gives 20 health.", "Ate the apple. Gained 20 health.", "hp = hp + 20\nif hp > maxHp: hp = maxHp")
drink = invObject("Drink", "Some kind of energy drink. Raises dodge chance to 75%.", "Drank the drink. Dodge chance is now 75%!", "dodgeChance = 75")

# Assign base inventory
inventory = [apple, drink, empty]

slot = int(input("Input slot number to use. ")) - 1
inventory[slot].use() # does not update values

# Show final stats
print("New HP value: " + str(hp))
print("Dodge chance: " + str(dodgeChance) + "%")
print()
print("Inventory contents:")
print("Slot 1: " + str(inventory[0].name))
print("Slot 2: " + str(inventory[1].name))
print("Slot 3: " + str(inventory[2].name))

EDIT 2: Another thing: the code works if I don't use exec() (e.g. change it out for hp += 20).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

如日中天 2025-01-19 13:07:01

exec() 有可选参数供您提供全局和局部变量上下文。

但你没有提供它们。

exec() has optional arguments for you to provide the global and local variable contexts.

But you didn't provide them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文