【问题标题】:Trying to call a function on an object试图在对象上调用函数
【发布时间】:2017-05-27 23:55:25
【问题描述】:

如果我先向您展示我的代码,这可能是最简单的:

def use(self):
    target = self.requestTarget()
    target = str(target)
    exec(self.whatDoes+"("+target+")")

self.requestTarget 返回player,一个对象。 self.whatDoes"learnAttack"learnAttack() 将一个对象作为其参数,并将一个项目附加到目标具有的列表中。 当我运行这段代码时,我得到了错误:

learnAttack(<character object at 0x7fda68acf1d0>)
            ^
SyntaxError: invalid syntax

诚然,我本可以更好地编写代码,但我设置了一个完整的框架,更改此代码将涉及很多我懒得做的工作。

很抱歉使用exec()

【问题讨论】:

  • 你想把什么传递给你的日常工作?除非您定义 __str__ 方法,否则对象上的 str 可能会返回那种输出。
  • 你为什么要使用exec
  • @JimFasarakis-Hilliard XY 问题,再次。
  • 制作self.whatDoes = learnAttack(函数,而不是字符串)。那么self.whatDoes(target)等价于learnAttack(target)
  • 你应该创建字典functions["learnAttack"] = learnAttack 然后你不需要exec()functions[self.whatDoes](target)。然后您不必将target 转换为string,因此SyntaxError 没有问题。

标签: python function python-3.x oop


【解决方案1】:

100 次中有 99.99 次,exec / eval 是错误的解决方案。

Python 函数(以及方法、类和模块 FWIW)是对象,所以如果你可以让 self.whatDoes 指向一个函数(或方法或任何可调用对象),那么你不需要 exec 或 @ 987654325@ - 您可以只应用带有预期参数的调用运算符,即:

def fun(obj):
    print(obj)

class Whatever(object):
    pass

w = whatever()
w.whatDoes = fun

w.whatDoes(42)

如果您需要 whatDoes 成为字符串,则构建允许的函数名称的 dict -> 函数并查找该字典:

def fun(obj):
    print(obj)

FUNCTIONS = {
    "fun": fun,
    # etc
}

class Whatever(object):
    def requestTarget(self):
        return 42

    def use(self):
        target = self.requestTarget()
        func =  FUNCTIONS[self.whatDoes]
        return func(target)

w = Whatever()
w.whatDoes = "fun"
w.use()

哦,是的,如果“whatDoes”应该是你的类的方法名,你可以使用getattr(obj,name)

【讨论】:

    【解决方案2】:

    先用eval创建函数并调用它。

     def use(self):
       target = self.requestTarget()
       target = str(target)
       func = eval(self.whatDoes)
       func(target)
    

    【讨论】:

      【解决方案3】:

      解决方法:将exec(self.whatDoes+"("+target+")")替换为exec(self.whatDoes+"(target)"),并去掉target = str(target)这一行

      这里的问题是,当你到达target = str(target) 行时,变量目标变成了字符串"&lt;character object at 0x7fda68acf1d0&gt;"。它不再引用原始对象,而只是引用那个字符串,它只是一个字符串。然后,当你的程序到达exec(self.whatDoes+"("+target+")") 时,它会作为learnAttack(&lt;character object at 0x7fda68acf1d0&gt;) 执行,这会导致明显的语法错误,因为运行会在任何地方导致错误。建议修复后,它会执行learnAttack(target),而目标仍然指向该对象。

      【讨论】:

      • 很理想,但是这个小伙子说他宁愿不改变其他东西,所以至少这是一个解决方案
      猜你喜欢
      • 2014-02-28
      • 2014-05-13
      • 2018-05-27
      • 1970-01-01
      • 2021-05-18
      • 2018-03-13
      • 1970-01-01
      • 2014-02-06
      • 2014-02-21
      相关资源
      最近更新 更多