zoukankan      html  css  js  c++  java
  • 绑定方法与非绑定方法

    类中定义函数分为了两大类,绑定方法与非绑定方法,它们有一些特殊之处:

    1、绑定方法特殊之处:绑定给谁就应该由谁来调用,谁来调用就会将谁当做第一个参数自动传入

      绑定给对象的方法:这个在面向对象第一篇第六节就讲到过(传送门),在类中定义函数没有被任何装饰器修饰的情况下,默认就是绑定对象的

      绑定给类的方法:为类中定义函数添加一个装饰器 classmethod,就是绑定类的

    2、非绑定方法特殊之处:非绑定方法就是一个普通函数,既不与类绑定又不与对象绑定,意味着类与对象都可以调用,但是无论谁来调用都是一个普通函数,没有自动传值效果,非绑定方法就是为类中定义函数添加一个装饰器 staticmethod

    类的绑定方法

    类中的方法,默认都是绑定给对象使用,所以需要采取一点措施,将类中的绑定方法解除对象绑定关系,进而绑定到类上,在 Python 中,引入了 classmethod 装饰器,将类中的方法绑定到类身上

    class People():
        @classmethod
        def talk(cls):
            pass
    
    p = People()
    print(People.talk)
    
    # 运行
    <bound method People.talk of <class '__main__.People'>>
    View Code

    从上述结果可以看出,加上了一个装饰器,将类中绑定给对象的方法,绑定到类身上了。之前分析过,如果一个方法绑定到谁身上,那么在调用该函数的时候,将自动将该调用者当作第一个参数传递到函数中。但是,绑定到类的方法与绑定到对象方法有一点点不同:

    class People:
        def __init__(self, name):
            self.name = name
    
        @classmethod
        def talk(cls):
            pass
    
    p = People('qiu')
    print(People.talk)
    print(p.talk)
    
    # 运行结果
    <bound method People.talk of <class '__main__.People'>>
    <bound method People.talk of <class '__main__.People'>>
    View Code

    也就是说,当对象在调用类的绑定方法时,也会默认把类当作参数传递进去!所以下面执行正常,并不会因为这个方法绑定到类身上,而对象调用没有传递参数,报错!

    class People:
        @classmethod
        def talk(cls):
            pass
    
    p = People()
    People.talk()
    p.talk()
    View Code

    但是,如果 talk() 没有参数,则下面代码均会报错

    class People:
        @classmethod
        def talk():
            pass
    
    p = People()
    People.talk()
    p.talk()
    
    #报错结果
    talk() takes 0 positional arguments but 1 was given
    View Code

    两者报错结果一致,这就说明了,当对象来调用类的绑定方法时,也是自动将类传递进去,并不需遵循函数参数传递的规则。

    绑定方法总结:类中方法默认都是绑定给对象使用,当对象调用绑定方法时,会自动将对象作为第一个参数传递进去;而类来调用,则必须遵循函数参数一一对应的规则,有几个参数,就必须传递几个参数。如果一个方法是用了 classmethod 装饰器,那么这个方法绑定到类身上,不管是对象来调用还是类调用,都会将类作为第一个参数传递进去。

    非绑定方法

    上面说了,类中的方法要么是绑定给对象使用,要么是绑定给类使用,那么有没有不绑定给两者使用的函数?

      答案是,当然有,Python 给我们提供了 staticmethod 装饰器,可以解除绑定关系,将一个类中的方法,变为一个普通函数

    import hashlib
    import time
    
    class MySQL:
        def __init__(self, host, port):
            self.id = self.create_id()
            self.host = host
            self.port = port
    
        @staticmethod
        def create_id():  # 就是一个普通工具
            m = hashlib.md5(str(time.clock()).encode('utf-8'))
            return m.hexdigest()
    
    print(MySQL.create_id)
    conn = MySQL('127.0.0.1', 3306)
    print(conn.create_id)
    
    # 运行结果
    <function MySQL.create_id at 0x0000021BEAAE9B70>
    <function MySQL.create_id at 0x0000021BEAAE9B70>
    View Code

    从上面的输出结果可以看出,使用了 staticmethod 装饰了一个函数,那么这个函数跟普通函数没有什么区别。既然是普通函数,那么就遵从函数参数传递规则,有几个参数就传递几个参数。

  • 相关阅读:
    [BestCoder Round #3] hdu 4907 Task schedule (模拟简单题)
    .NET中的PublicKeyToken以及强命名问题
    bug统计分析续(一)基于SQL的Bug统计方法
    iOS项目开发实战——通过Http Get方式与server通信
    TCP与UDP的区别(转)
    Telit GPRS模块测试报告
    GPRS优点介绍及GPRS上网相关知识(转)
    MC34063中文资料及应用实例(转)
    MC34063+MOSFET扩流 12V-5V 折腾出了高效率电路(转)
    Bluez SPP实现代码分析(转)
  • 原文地址:https://www.cnblogs.com/qiuxirufeng/p/9850612.html
Copyright © 2011-2022 走看看