Python:将class方法赋值给一个变量
Python: Assigning class method to a variable
我在 class 中有很多方法,我需要调用一个特定的方法。我试过这样的东西,但得到了一个 AttributeError
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
那么有什么办法吗?
class 中的函数定义应包含 '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
我们应该在这里讨论几件事。我将尝试解释不同的场景,让您大致了解发生了什么。
首先让我们看看你的最后一行:
my_obj.first_func(a, b) + my_obj.second_func(a, b)
您正在尝试从实例 my_obj
获取 first_func
属性。它(或者它是class)有那个吗? 没有
first_func
是全局模块中的一个变量。 my_obj
对此一无所知。
所以你的异常是因为这个...
现在考虑你的方法:
first
和 second
方法是 class 中的常规方法。当您说 MyClass.first
时,您得到的是函数对象 而不是方法 。此函数接受两个参数 a
和 b
.
但是如果你说 my_obj.first_func
你会得到一个 方法对象 它有一个绑定的实例对象。 Python 使用对调用此方法的实例的引用为您填充第一个参数。现在你的方法对象只接受一个参数b
。 (这就是描述符的工作原理)
话虽如此,您在这里有一些选择:
1 - 仅从 class 而不是实例调用它们:
否则你会得到异常,因为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
:
装饰它们
现在您可以从实例调用或 class,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 中调用它们,则需要将其作为第一个参数传递。
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))
我在 class 中有很多方法,我需要调用一个特定的方法。我试过这样的东西,但得到了一个 AttributeError
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
那么有什么办法吗?
class 中的函数定义应包含 '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
我们应该在这里讨论几件事。我将尝试解释不同的场景,让您大致了解发生了什么。
首先让我们看看你的最后一行:
my_obj.first_func(a, b) + my_obj.second_func(a, b)
您正在尝试从实例 my_obj
获取 first_func
属性。它(或者它是class)有那个吗? 没有
first_func
是全局模块中的一个变量。 my_obj
对此一无所知。
所以你的异常是因为这个...
现在考虑你的方法:
first
和 second
方法是 class 中的常规方法。当您说 MyClass.first
时,您得到的是函数对象 而不是方法 。此函数接受两个参数 a
和 b
.
但是如果你说 my_obj.first_func
你会得到一个 方法对象 它有一个绑定的实例对象。 Python 使用对调用此方法的实例的引用为您填充第一个参数。现在你的方法对象只接受一个参数b
。 (这就是描述符的工作原理)
话虽如此,您在这里有一些选择:
1 - 仅从 class 而不是实例调用它们:
否则你会得到异常,因为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
:
装饰它们
现在您可以从实例调用或 class,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 中调用它们,则需要将其作为第一个参数传递。
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))