有几件事我们应该在这里讨论。我将试着解释不同的场景,给你们一个概览,看看发生了什么。
首先让我们看看你的最后一行:
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))