【问题标题】:How to dynamically call methods within a class using method-name assignment to a variable [duplicate]如何使用方法名分配给变量来动态调用类中的方法[重复]
【发布时间】:2013-05-14 13:49:07
【问题描述】:
class MyClass:
    def __init__(self, i):
        self.i = i

    def get(self):
        func_name = 'function' + self.i
        self.func_name() # <-- this does NOT work.

    def function1(self):
        pass # do something

    def function2(self):
        pass # do something

这给出了错误:TypeError: 'str' object is not callable

我该怎么做呢?

注意:self.func_name 也不起作用

【问题讨论】:

  • 根据您的使用情况,您最好使用函数列表/字典,或者使用 lambda 函数将附加参数传递给函数(后者主要用于回调)。
  • 这不是您收到此错误的代码。当您执行self.func_name 时,您甚至无法访问局部变量func_name。您正在尝试访问 self 内部名为 class name 的实例变量 - 但这样的变量不存在。
  • @Elazar 是的,我的错。我正在翻译代码,错过了这个。
  • 本题与3061题有细微差别。本题重点介绍类中的方法调用。 3061专注于常规功能。 Python 新手可能无法将那里写的答案应用于这种情况。
  • 投票重新开放。我被称为新手,我完全不明白这是如何与链接问题重复。

标签: python


【解决方案1】:
def get(self):
      def func_not_found(): # just in case we dont have the function
         print 'No Function '+self.i+' Found!'
      func_name = 'function' + self.i
      func = getattr(self,func_name,func_not_found) 
      func() # <-- this should work!

【讨论】:

  • 非常感谢您的回复。仅供大家参考,也可以给一个默认值来避免异常。例如,'func = getattr(self, func_name, None)'。来自 python help (= help(getattr)):“当给出默认参数时,当属性不存在时返回它;没有它,在这种情况下会引发异常。”
  • 如何进行单元测试?我试过了,但是当我断言函数调用时,它给了我错误
【解决方案2】:

两件事:

  1. 在第 8 行使用,

    func_name = '函数' + str(self.i)

  2. 定义一个字符串到函数的映射,

      self.func_options = {'function1': self.function1,
                           'function2': self.function2
                           }
    
  3. 所以它应该看起来像:

    我的班级:

    def __init__(self, i):
          self.i = i
          self.func_options = {'function1': self.function1,
                               'function2': self.function2
                               }
    def get(self):
          func_name = 'function' + str(self.i)
          func = self.func_options[func_name]
          func() # <-- this does NOT work.
    
    def function1(self):
          //do something
    
    def function2(self):
          //do something
    

【讨论】:

  • 这应该也可以。但是 getattr 解决方案是一个非常干净的解决方案,我们都可以使用。再次感谢 Sinhayash 提供的这个新颖的解决方案。解决其他一些相关问题可能很有用。谢谢。
猜你喜欢
  • 2018-05-20
  • 1970-01-01
  • 2011-11-14
  • 1970-01-01
  • 2011-04-20
  • 1970-01-01
  • 1970-01-01
  • 2020-04-15
相关资源
最近更新 更多