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

    类中定义的函数分为两大类

    1、绑定方法

    1.1、绑定到类的方法:用classmethod装饰器的方法

    为类量身定制

    类.bound_method(),自动将类当作第一个参数传入

    (其实对象也可调用,但任然将类当作第一个参数传入)

    class Foo:
        def __init__(self,name):
            self.name = name
        def tell(self):
            print(f"名字{self.name}")
        @classmethod # 把类本身当作第一个参数
        def func(cls):  # cls = Foo
            print(cls)
    f = Foo('LELE')
    Foo.func()
    结果:
    <class '__main__.Foo'>

    1.2、绑定到对象的方法:没有被任何装饰器装饰的方法

    为对象量身定制

    对象.bound\_method(),自动将对象当作第一个参数传入

    (属于类的函数,类可以调用,但必须按照函数的规则来,没有自动传值那么一说)

    class Foo:
        def __init__(self,name):
            self.name = name
        def tell(self):
            print(f"名字{self.name}")
    f = Foo('LELE')
    print(f.tell())
    print(f.tell)

    2、非绑定方法(不与类或者对象绑定):用staticmethod装饰器装饰的方法

    不与类或对象绑定,类和对象都可以调用,但没有自动传值那么一说。就是一个普通工具而已

    注意:与绑定到对象方法区分开,在类中直接定义的函数,没有被任何装饰器装饰的,都是绑定到对象的方法,可不是普通函数,对象调用该方法会自动传值,

    而staticmethod装饰的方法,不管谁来调用,都没有自动传值一说

    #=====非绑定方法----对象和类都可以用
    class Foo:
        def __init__(self,name):
            self.name = name
        def tell(self):# 绑定方法,绑定给对象
            print(f"名字{self.name}")
        @classmethod # 绑定方法:绑定给类 把类本身当作第一个参数
        def func(cls):  # cls = Foo
            print(cls)
    
        @staticmethod  # 非绑定方法 
        def func2(x,y):  
            print(x+y)
    
    f = Foo('LELE')
    Foo.func2(1,2) #
    f.func2(1,4) 
    类内部定义的函数:

    绑定方法:绑定给对象 ,在内部创建的函数没有装饰器;绑定给类,有装饰器@classmethod把类本身当作第一个参数

    非绑定方法:@staticmethod普通函数,谁都可调用

     3、练习题

    练习1:定义MySQL类
    
    要求:
    
    1.对象有id、host、port三个属性
    
    2.定义工具create_id,在实例化时为每个对象随机生成id,保证id唯一
    
    3.提供两种实例化方式,方式一:用户传入host和port 方式二:从配置文件中读取host和port进行实例化
    
    4.为对象定制方法,save和get_obj_by_id,save能自动将对象序列化到文件中,文件路径为配置文件中DB_PATH,文件名为id号,保存之前验证对象是否已经存在,若存在则抛出异常,;get_obj_by_id方法用来从文件中反序列化出对象
    import conf
    import hashlib,time,os,sys,pickle
    
    BASE_DIR = os.path.dirname(os.path.abspath(__file__))
    sys.path.append(BASE_DIR)
    
    class MySQL:
        def __init__(self,host,port):#对象的初始化操作是自动完成的
            self.host = host
            self.port = port
            self.id = MySQL.create_id()
    
        @staticmethod # 非绑定方法
        def create_id():
            #m = hashlib.md5()
            m = hashlib.md5(str(time.time()).encode('utf-8'))
            #m.update(bytes(str(m),encoding='utf-8'))
            return m.hexdigest()
    
        def tell(self):
            print(f"{self.id},{self.host},{self.port}")
    
        def save(self):
            id_filename = os.path.join(conf.DB_PATH,self.id+'.txt') #结合目录名和文件名
            print(id_filename)
            with open(id_filename,'wb') as f:
                return pickle.dump(self,f)
    
        @classmethod # 绑定方法 MySQL(conf.host,conf.port)
        def get_obj_by_id(cls,filename):
            id_filename = os.path.join(conf.DB_PATH,filename+'.txt')
            with open(id_filename,'rb') as f:
                return  pickle.load(f)
    
        @classmethod # 绑定方法
        def id_from_conf(cls):  #本题为类绑定 MySQL(conf.host,conf.port)
            return cls(conf.host,conf.port)
    # # 用户传入host和port
    user1 = MySQL('127.0.0.1',80)
    user1.tell()
    #
    # # save能自动将对象序列化到文件中
    user1.save()
    
    
    # 从配置文件中读取host和port进行实例化
    user2 = MySQL.id_from_conf()
    user2.tell()
    
    #get_obj_by_id方法用来从文件中反序列化出对象
    user3 = MySQL.get_obj_by_id('d1f533ec8be01c54279e675188aa71e2')
    user3.tell()

    配置文件conf.py代码:

    import os,sys
    DB_PATH = os.path.dirname(os.path.abspath(__file__))
    sys.path.append(DB_PATH)
    host = '127.0.1.2'
    port = 20

    保存的时候生成文件:

  • 相关阅读:
    [51nod1247]可能的路径(思维题)
    天梯赛L1020 帅到没朋友(map的使用)(模拟,数组非排序去重)
    洛谷 p1030 树的遍历
    天梯赛L1046 整除光棍(模拟)
    牛客,并查集,简单dp经商
    天梯赛L1043 阅览室 模拟题
    天梯赛L1049(模拟+vector的使用)
    天梯赛L1011,简单模拟
    codeforces 1201 c
    天梯赛L2003月饼(简单排序题)
  • 原文地址:https://www.cnblogs.com/foremostxl/p/9601161.html
Copyright © 2011-2022 走看看