一、绑定方法
1. 绑定方法的定义:凡是类中的方法或函数,默认情况下都是绑定给对象使用的。
- 类中不被任何装饰器装 装饰的方法或函数,默认情况下都是绑定给对象使用的,例如 def fun() 或 def fun(self)
- 用@classmethod装饰的方法是绑定到类上的
- 用@staticmethod修饰的方法,是解除所有绑定关系作为普通函数存在,为非绑定方法
2. 绑定方法的特点:
- 其特点是「调用方」本身自动作为第一个参数传入。
- 一个方法绑定到谁身上,谁来调用,该调用者当作第一个参数会自动传参。
- 绑定给对象:调用方是一个「对象」,该对象自动传入(调用方是『类』,需要手动传入第一个参数)
- 绑定给类:调用方是「类|对象」,该类自动传入
3. 绑定方法的分类:
- 绑定到类的方法:
- 用classmethod装饰器装饰的方法就是类绑定方法(「对象」也可调用「类绑定方法」,但仍将类当作第一个参数传入)。
- 类.boud_method(),自动将「类」当作第一个参数传入
- 对象.boud_method(),自动将「类」当作第一个参数传入
- 绑定到对象的方法:
- 没有被任何装饰器装饰的方法,默认是绑定给对象使用的方法。
- 对象.boud_method(args2,args3),自动将“对象”当作第一个参数传入。
- 类.boud_method(args1,args2,args3),需按照参数规则一一传递所有参数
-- “类”可以调用“对象的绑定方法”,但不会自动传值,需按照参数规则一一传递所有参数
二、 非绑定方法:
1. 非绑定方法的定义:在类内部用@staticmethod装饰的函数即「非绑定方法」,就是普通函数。
2. 非绑定方法的特点:
- 不与类或对象绑定
- 没有自动传参的效果
- 『类和对象』都可以调用
- 不管谁来调用,都不会自动传值
3. 【答疑】
- 自由方法应该也算非绑定方法?-- 自由方法是对象的绑定方法,绑定给对象。
- 如果定义staticmethod时传self或cls,还算是非绑定方法吗?
-- 在静态方法里面 访问不了 类或者实例 的任何属性。 一般不需要传参数self
【注意】在类中直接定义的函数,没有被任何装饰器装饰的,都是绑定到对象的方法,不是普通函数,对象调用该方法会自动传值
三、总结:
当「对象」调用「对象的绑定方法」时,默认把对象自己当做第一个参数传递到函数中
当 「类」 调用「对象的绑定方法」时,不会进行自动传值的;也就是说,函数有几个参数,我们就得传递进去几个参数。
当「类|对象」在调用「类的绑定方法」时,会默认把 类 当作参数传递进去。
当「类|对象」在调用「非绑定方法」时,不会自动传值
四、代码示例
# 对象的绑定方法
# 当“对象” 调用对象的绑定方法时,会默认把 对象当作 第一个参数传递进去.
# 当 “类” 调用对象的绑定方法时,不会默认传参,需要一一传参
class People:
def __init__(self,name):
self.name = name
# 对象的绑定方法
def object_has_args(self): # 这是对象的绑定方法
print("Here is 'object_has_args'")
def object_no_args(): # 这也是对象的绑定方法
print("Here is 'object_no_args'")
p = People('xiaohua')
# 对象的绑定方法:有参数+无参数
# >>>>>>类中无任何装饰器的方法或函数,默认情况下都是绑定给对象使用的,例如 def f() 或 def f(self) <<<<<
print(p.object_has_args) # <bound method People.talk of <__main__.People object at xxxxx
print(p.object_no_args) # <bound method People.talk of <__main__.People object at xxxxx
p.object_has_args() # 对象来调用,仅仅是当作函数使用
p.object_no_args() # 报错,这里会传参对象p给函数;takes 0 positional arguments but 1 was given
print(People.object_no_args) # <function People.object_no_args at 0x7f874422c040>
print(People.object_has_args) # <function People.object_no_args at 0x7f874422c040>
People.object_no_args() # 类来调用,仅仅是当作函数使用
People.object_has_args("需要手动传参") # 对比测试
People.object_has_args() # 报错,类调用方法时,不会自动传参;missing 1 required positional argument: 'self'
# 调用类的绑定方法时,会默认把类当作参数传递进去.
class People:
def __init__(self,name):
self.name = name
# 类的绑定方法
@classmethod
def classmethod_has_args(cls):
print("有参数")
@classmethod
def classmethod_no_args():
print("无参数")
p = People('xiaohua')
# 类的绑定方法:有参数+无参数
# >>>>>>>>当「对象|类」在调用类的绑定方法时,会默认把类当作参数传递进去<<<<<<<<
p.classmethod_has_args() # 类的绑定方法:当对象在调用类的绑定方法时,也会默认把类当作参数传递进去
People.classmethod_has_args() # 类的绑定方法:默认把『类』当做第一个参数传入
p.classmethod_no_args() # 报错,takes 0 positional arguments but 1 was given
People.classmethod_no_args() # 报错,takes 0 positional arguments but 1 was given
print(People.classmethod_has_args) # 类的绑定方法:<bound method People.talk of <class '__main__.People'>>
print(p.classmethod_has_args) # 类的绑定方法:<bound method People.talk of <class '__main__.People'>>
print(p.classmethod_no_args) # 类的绑定方法:<bound method People.talk of <class '__main__.People'>>
print(People.classmethod_no_args) # 类的绑定方法:<bound method People.talk of <class '__main__.People'>>
# 非绑定方法:遵从函数参数传递规则,有几个参数就传递几个参数
class People:
def __init__(self,name):
self.name = name
# 非绑定方法
@staticmethod
def staticmethod_no_args():
print('xx')
@staticmethod
def staticmethod_has_args(stm):
print(f"Here is: {stm}")
p = People('xiaohua')
# 非绑定方法:有几个参数就传递几个参数
print(p.staticmethod_has_args)
print(People.staticmethod_has_args)
print(p.staticmethod_no_args)
print(People.staticmethod_no_args,"\n")
p.staticmethod_no_args() #
People.staticmethod_no_args()
p.staticmethod_has_args("对象")
People.staticmethod_has_args("类") #
'''
<function People.staticmethod_has_args at 0x7fb06a22b160>
<function People.staticmethod_has_args at 0x7fb06a22b160>
<function People.staticmethod_no_args at 0x7fb06a22b040>
<function People.staticmethod_no_args at 0x7fb06a22b040>
xx
xx
Here is: 对象
Here is: 类
'''