Py学习  »  Python

Python:将类方法分配给变量

JustUsNow • 2 年前 • 983 次点击  

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

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

有没有办法做到这一点?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/132045
 
983 次点击  
文章 [ 3 ]  |  最新文章 2 年前
SorousH Bakhtiary
Reply   •   1 楼
SorousH Bakhtiary    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))
Akash garg
Reply   •   2 楼
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
stellasia
Reply   •   3 楼
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 (方法)