三行代码  ›  专栏  ›  技术社区  ›  JustUsNow

Python:将类方法分配给变量

  •  0
  • JustUsNow  · 技术社区  · 2 月前

    我在一个类中有很多方法,我需要调用一个特定的方法。我试过这样的方法,但却发现了一个属性错误

    class MyClass:
        def first(a, b):
            return a + b
        def second(a, b):
            return a * b
    
    a = 2
    b = 3
    
    first_func = MyClass.first
    second_func = MyClass.second
    
    my_obj = MyClass()
    

    我希望下面的东西能起作用,但我有个例外:

    my_obj.first_func(a, b) + my_obj.second_func(a, b) == 11
    

    有没有办法做到这一点?

    2 回复  |  直到 2 月前
        1
  •  0
  •   stellasia    2 月前

    因为你的方法没有 self 参数,它们是“静态”的,不依赖于指定的对象。可以这样调用函数:

    first_func(a, b)  # no my_obj
    

    如果事实上它们确实依赖于对象,你会写道:

    class MyClass:
        def first(self, a, b):
            return a + b
        def second(self, a, b):
            return a * b
    

    你可以在对象上调用方法:

    my_obj = MyClass()
    my_obj.first(a, b)
    

    或者,用你的初始符号:

    first_func = MyClass.first
    first_func(my_obj, a, b)
    

    (你的朋友也一样 second (方法)

        2
  •  0
  •   Akash garg    2 月前

    类中的函数定义应包含“self”作为参数

    class MyClass:
        def first(self,a, b):
            return a + b
        def second(self,a, b):
            return a * b
    
    a = 2
    b = 3
    
    first_func = MyClass.first
    second_func = MyClass.second
    
    my_obj = MyClass()
    first_func(my_obj,a, b) + second_func(my_obj,a, b) == 11
    
        3
  •  0
  •   S.B    2 月前

    有几件事我们应该在这里讨论。我将试着解释不同的场景,给你们一个概览,看看发生了什么。

    首先让我们看看你的最后一行:

    my_obj.first_func(a, b) + my_obj.second_func(a, b)
    

    你是想得到 first_func 来自实例的属性 my_obj .它(或它的班级)有吗?
    第一_func 是全局模块中的一个变量。 我的obj 对此一无所知。

    所以你的例外是因为这个。。。


    现在考虑一下你的方法:
    first second 方法是类中的常规方法。当你说 MyClass.first ,您将获得一个函数对象 不是一种方法 .此函数接受两个参数 a b .

    但是如果你说 my_obj.first_func 你得到一个 方法对象 它有一个绑定实例对象。Python用对调用此方法的实例的引用来填充第一个参数。现在,您的方法对象只接受一个参数 B (这就是描述符的工作原理)

    话虽如此,你在这里有一些选择:

    1-仅从类而不是实例调用它们:

    否则会出现异常,因为Python已经用实例对象填充了第一个参数。

    class MyClass:
        def first(a, b):
            return a + b
    
        def second(a, b):
            return a * b
    
    first_func = MyClass.first
    second_func = MyClass.second
    print(first_func(2, 3) + first_func(2, 3))
    

    2.用绿色装饰 staticmethod :

    现在可以从实例或类调用,Python不会为您填充第一个参数。

    class MyClass:
        @staticmethod
        def first(a, b):
            return a + b
    
        @staticmethod
        def second(a, b):
            return a * b
    
    first_func = MyClass.first
    second_func = MyClass.second
    print(first_func(2, 3) + first_func(2, 3))
    
    class MyClass:
        @staticmethod
        def first(a, b):
            return a + b
    
        @staticmethod
        def second(a, b):
            return a * b
    
    my_obj = MyClass()
    first_func = my_obj.first
    second_func = my_obj.second
    print(first_func(2, 3) + first_func(2, 3))
    

    3-添加一个 self 参数(其名称不是规则,而是强烈建议的约定):

    这一次,如果从实例调用它们,则不需要将实例传递给第一个参数,但如果从类调用它们,则需要将其作为第一个参数传递。

    class MyClass:
        def first(self, a, b):
            return a + b
    
        def second(self, a, b):
            return a * b
    
    
    my_obj = MyClass()
    first_func = my_obj.first
    second_func = my_obj.second
    print(first_func(2, 3) + first_func(2, 3))
    
    class MyClass:
        def first(self, a, b):
            return a + b
    
        def second(self, a, b):
            return a * b
    
    
    my_obj = MyClass()
    first_func = MyClass.first
    second_func = MyClass.second
    print(first_func(my_obj, 2, 3) + first_func(my_obj, 2, 3))