Python 绑定方法与非绑定方法详解

一、绑定方法

1. 绑定方法的定义:凡是类中的方法或函数,默认情况下都是绑定给对象使用的。

  • 类中不被任何装饰器装 装饰的方法或函数,默认情况下都是绑定给对象使用的,例如 def fun()  或 def fun(self)

  • 用@classmethod装饰的方法是绑定到类上的

  • 用@staticmethod修饰的方法,是解除所有绑定关系作为普通函数存在,为非绑定方法

2. 绑定方法的特点:

  • 其特点是「调用方」本身自动作为第一个参数传入。

  • 一个方法绑定到谁身上,谁来调用,该调用者当作第一个参数会自动传参。

  • 绑定给对象:调用方是一个「对象」,该对象自动传入(调用方是『类』,需要手动传入第一个参数)

  • 绑定给类:调用方是「类|对象」,该类自动传入

3. 绑定方法的分类:

  1. 绑定到类的方法:

  • 用classmethod装饰器装饰的方法就是类绑定方法(「对象」也可调用「类绑定方法」,但仍将类当作第一个参数传入)。

  • 类.boud_method(),自动将「类」当作第一个参数传入

  • 对象.boud_method(),自动将「类」当作第一个参数传入

  1. 绑定到对象的方法:

  • 没有被任何装饰器装饰的方法,默认是绑定给对象使用的方法。

  • 对象.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: 类
'''

 

 
posted @ 2022-11-04 15:50  yudai  阅读(584)  评论(0编辑  收藏  举报