Python的绑定方法与非绑定方法

绑定方法与非绑定方法

类中定义的函数分为两大类:绑定方法和非绑定方法。

一、绑定方法

# encoding=utf-8
# auther:lsj
# 绑定方法与非绑定方法
# classmethod
# 一、绑定方法:特殊之处在于将调用者本身当作第一个参数自动传入
#     1、绑定给对象的方法:调用者是对象,自动传入的是对象。
#     2、绑定给类的方法:调用者是类,自动传入的是类,使用classmethod。
class Mysql:
    def __init__(self,ip,port):  # 这里的self接受传入的对象
        self.ip = ip
        self.port = port
    def func(self):  # 此时的函数体接受的是对象,绑定的就应该是对象
        print('%s:%s'%(self.ip,self.port))

# 实例化举例一
obj1 = Mysql('1.1.1.1',3306)

# 实例化举例二
# encoding=utf-8
# auther:lsj
# 
# 需求:从配置文件中获取IP和PORT,传给类完成实例化操作。
IP= '127.0.0.1'
PORT = 3306
# 需求:从配置文件中获取IP和PORT,传给类完成实例化操作。
# import day030.setting
from day030 import settings
obj2 = Mysql(settings.IP,settings.PORT)
# 因为上面实例化举例二中太麻烦,所以实例化举例三
2、绑定给类的方法:调用者是类,自动传入的是类,使用@classmethod
from day030 import settings
class Mysql:
    def __init__(self,ip,port):  # 这里的self接受传入的对象
        self.ip = ip
        self.port = port
    def func(self):  # 此时的函数体接受的是对象,绑定的就应该是对象
        print('%s:%s'%(self.ip,self.port))

    # def from_conf():
        # return Mysql(settings.IP,settings.PORT)
    @classmethod  # 绑定给类的方法,将下面的函数装饰成绑定给类的方法
    def from_conf(cls):
        print(cls)
        return cls(settings.IP,settings.PORT)

# Mysql.from_conf()  # 绑定到类的方法<class '__main__.Mysql'>
obj3 = Mysql.from_conf()
print(obj3.__dict__)  # 调用类方法,自动将类MySQL当作第一个参数传给cls{'ip': '127.0.0.1', 'port': 3306}

总结:在类中正常定义的函数默认是绑定到对象的,而为某个函数加上装饰器@classmethod后,该函数就绑定到了类。

  绑定到类的方法就是专门给类用的,但其实对象也可以调用,只不过自动传入的第一个参数仍然是类,也就是说这种调用是没有意义的,
并且容易引起混淆,这也是Python的对象系统与其他面向对象语言对象系统的区别之一,比如Smalltalk和Ruby中,绑定到类的方法与绑定到对象的方法是严格区分开的。

 二、非绑定方法

# encoding=utf-8
# auther:lsj
# 类中的函数一个是绑定给对象用,一个是绑定给类用
# 非绑定方法-->静态方法
#     没有绑定给任何人:调用者可以是类,也可以是对象,没有自动传参的效果。
# 思考:有没有一种函数即不需要传递类也不需要传递对象,就是一个独立的功能
class Mysql:
    def __init__(self,ip,port):
        # self.nid =
        self.ip = ip
        self.port = port

    @staticmethod  # 将下述函数装饰成一个静态方法,非绑定方法
    # 创建一个id号
    def create_id(): # 此时的函数体代码既不依赖于类,也不依赖于对象import uuid
        return uuid.uuid4()
obj1 = Mysql('1.1.1.1',3306)

print(Mysql.create_id)  # <function Mysql.create_id at 0x0000017C4D0A1550>
print(obj1.create_id)      # <function Mysql.create_id at 0x0000017C4D0A1550>
# 类中的函数一个是绑定给对象用,一个是绑定给类用
# 非绑定方法-->静态方法
class Mysql:
    def __init__(self,ip,port):
        # self.nid =
        self.ip = ip
        self.port = port

    @staticmethod  # 将下述函数装饰成一个静态方法,非绑定方法
    def create_id(x,y,z): # 此处有几个参数下面实例的时候也要传入几个参数。 
        print(x,y,z)
        import uuid
        return uuid.uuid4()
obj1 = Mysql('1.1.1.1',3306)

Mysql.create_id(1,2,3) # 1 2 3
obj1.create_id(4,5,6)  # 4 5 6

三、绑定类,绑定对象,非绑定方法三者比较

class Mysql:
    def __init__(self,ip,port):
        # self.nid =
        self.ip = ip
        self.port = port

    @staticmethod  # 将下述函数装饰成一个静态方法,非绑定方法
    # 创建一个id号
    def create_id(): # 此时的函数体代码既不依赖于类,也不依赖于对象
        import uuid
        return uuid.uuid4()

    @classmethod
    def f1(cls):  # 加入@classmethod绑定给类
        pass
    def f2(self):  # 不加任何装饰默认绑定给对象
        pass
obj1 = Mysql('1.1.1.1',3306)

print(Mysql.create_id) # 非绑定方法:<function Mysql.create_id at 0x000001BCEDFC1550>
print(Mysql.f1) # 绑定给类:<bound method Mysql.f1 of <class '__main__.Mysql'>>
print(obj1.f2)  # 绑定给对象:<bound method Mysql.f2 of <__main__.Mysql object at 0x000001BCEDF1E070>>

 

原文地址:https://www.cnblogs.com/liunaixu/p/12879302.html