【问题标题】:How can I call a method stored in a variable?如何调用存储在变量中的方法?
【发布时间】:2018-01-23 18:13:36
【问题描述】:

如果我有一个带有方法method1 的类Foo,有没有办法将此方法存储在变量before 实例化中,然后我可以调用它after em> 这个类被实例化了吗?

例如:

class Foo:
    def method1(self, arg):
        print(self, arg)

# something like this variable, but which can be called with instantiated class 
func = Foo.method1

foo = Foo()
foo.func(1)  # I want to call it in a similar way to this

【问题讨论】:

  • 哦,我从来没有意识到对于未实例化的类,方法会以这种方式表现。这回答了我的问题。
  • 我打算以后把这个问题作为重复的目标,所以我稍微修改了一下,让它更短更切题。

标签: python class methods


【解决方案1】:

除了Rawing's 出色的答案之外,如果您访问的只是静态或类属性,您可能不需要实例化该类:

class Container:
    class_var = "class_var"
    def __init__(self, inst_var):
        self.inst_var = inst_var
        print("Instantiated")

    @staticmethod
    def static_mtd(static_arg):
        print(static_arg)

    def instance_mtd(self):
        print(self.inst_var)

    @classmethod
    def class_mtd(cls):
        print(cls.class_var)

stat = Container.static_mtd
stat("static_arg")  # static_arg

inst = Container.instance_mtd
inst(Container("inst_var"))   # Instantiated, inst_var

inst2 = Container("inst_var2").instance_mtd   # Instantiated
inst2()  # inst_var2

clas = Container.class_mtd
clas()  # class_var

var = Container.class_var # class_var

因此,您可以先将变量名称 inst 分配给实例方法 Container.instance_mtd,然后再实例化 class,然后将实例化的 class 作为 self 参数返回到 inst。这当然是相当乏味的,这意味着你重新分配的实例方法是在类之外有效地定义的。

【讨论】:

    【解决方案2】:

    在 python 中,函数和方法之间没有真正的区别——方法只是在类中定义的函数。

    对我们来说,这意味着存储在变量func 中的函数可以像任何其他函数一样被调用。如果func 引用Foo.method1,它是一个有2 个参数的函数:selfarg。为了调用func,我们只需传递一个Foo 实例作为self 参数和另一个值作为arg 参数:

    func(foo, 1)
    

    我们通常不必为self 传递参数的原因是因为通过实例访问方法会自动将函数 method1 变成绑定方法,其中隐式传递 self 参数:

    >>> Foo.method1  # Foo.method1 is a function
    <function Foo.method1 at 0x7f9b3c7cf0d0>
    >>>
    >>> foo.method1  # but foo.method1 is a bound method!
    <bound method Foo.method1 of <__main__.Foo object at 0x7f9b3c7dd9e8>>
    

    有关函数和方法的更多详细信息,请参阅this question

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-06
      • 1970-01-01
      • 2018-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-07
      • 2016-08-27
      相关资源
      最近更新 更多