【问题标题】:Pass method to function using method name from string variable使用字符串变量中的方法名称将方法传递给函数
【发布时间】:2020-06-20 00:23:15
【问题描述】:

我有一个带有构造函数的类、两个其他方法和一个包含这两个方法名称的成员列表。

class Foo():
    def __init__(self):
        self.methods = ["self.foo", "self.bar"]
    def foo(self):
        print("foo")
        return 0
    def bar(self):
        print("bar")
        return 0

我有一个将函数作为参数的函数,像这样。

myFunction(func)

该函数具有全局范围,可以这样使用。

myFunction(self.foo)

我想遍历 self.methods 列表中的项目并为每个方法名称调用函数,但正如预期的那样,传递的是字符串而不是方法本身。我如何通过像上面的例子这样的方法,所以像self.foo 而不是"self.foo"

【问题讨论】:

  • 您的myFunction 作用域在哪里?它是Foo 的一部分还是独立的?如果它要尝试按名称调用函数,是否有任何理由不接受要使用的实例的参数或...?
  • @JonClements myFunction 具有全局范围。你所说的要使用的东西的实例是什么意思?
  • myFunction 如何知道它应该查看哪些对象的方法并循环并运行这些方法?
  • 我仍然在为你在这里真正想要实现的目标而苦苦挣扎......但我会猜测你有一个foo = Foo()(和self.methods = ['foo', 'bar']) ,那么你可以做for f in foo.methods: getattr(foo, f)()...
  • @JonClements getattr() 正是我要找的,感谢您的帮助!

标签: python python-3.x string list oop


【解决方案1】:

据我了解,你可以试试这个。

class Foo():
    def __init__(self):
        self.method=['foo','bar']
    def foo(self):
        print('foo')
    def bar(self):
        print('bar')
    def run_all(self):
        for m in self.method:
            getattr(self,m)()

a=Foo()
a.run_all() # iterating through self.method and executing them
# foo
# bar

【讨论】:

  • 这正是我要找的,但self.method 不能是字典,它只能是只包含字符串的列表。
  • run_method 是一个奇怪的名字,考虑到它实际上并没有运行任何东西 - 它只是进行属性查找......我要么重命名它,要么实际上让它调用方法,然后由于您在该函数中具有执行此操作的逻辑,因此实际上在 run_all 中调用它,而不是用 getattr 的东西重复自己
  • @JonClements 同意。编辑答案。谢谢你的建议。 ;)
  • 这看起来正是我正在寻找的,但由于某种原因,我在执行 a.run_method('foo')() 时得到了 TypeError: 'NoneType' object is not callable
【解决方案2】:

你想要这样的东西吗?

class Foo():
    def __init__(self):
        self.methods = [self.foo(), self.bar()]
    def foo(self):
        print("foo")
        return 0
    def bar(self):
        print("bar")
        return 0


foo_obj = Foo()

【讨论】:

  • 这将调用__init__ 中的函数,然后将它们的结果存储在self.methods- 所以一旦你创建了Foo 实例,你就会得到 foo / bar打印,然后 self.methods = [0, 0]... 这可能不是 OP 的意图
  • self.methods 必须是字符串,这就是我无法理解如何操作的原因
【解决方案3】:

怎么样:

class Foo():
    def __init__(self):
        self.methods = self.foo, self.bar

    def run_methods(self):
        for method in self.methods:
            print('Running method {}'.format(method.__name__))
            method()

    def foo(self):
        print("foo")
        return 0

    def bar(self):
        print("bar")
        return 0

因此,您可以通过调用 run_methods 来运行您的方法。如果您还想访问他们的名字,您可以随时通过他们各自的__name__ 方法来实现,如上所述。

f = Foo()
f.run_methods() 

# Output:
#
# Running method foo
# foo
# Running method bar
# bar

编辑:正如另一个人建议的那样,您应该编辑您的问题以更详细地描述 myFunction(fun) 的作用。但是,您可能应该使用不同于将实际名称作为字符串传递的方法。

【讨论】:

  • OP 提到传递的是字符串而不是方法本身。
  • 确实.. 现在我重新阅读并无法理解他们到底想用 myFunction 做什么
  • 是的,我也不明白 OP 想要做什么。
  • 似乎 OP 在另一个答案中说过 self.methods 必须是字符串,这就是我在理解如何做时遇到的问题 ...所以这个答案很可能很接近......只需离开self.methods = ['foo', 'bar'],然后修改你的run_methods以使用getattr(self, method)()而不是method()(你的打印将是print('running', method)或类似的
猜你喜欢
  • 2014-12-31
  • 2018-07-03
  • 2016-12-03
  • 2020-10-27
  • 1970-01-01
  • 1970-01-01
  • 2012-04-15
  • 2017-07-21
  • 1970-01-01
相关资源
最近更新 更多