zoukankan      html  css  js  c++  java
  • 面向对象之绑定方法与非绑定方法

    一、类中函数的分类

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

    二、绑定方法

      1、定义:绑定给谁,谁来调用就自动将它本身当作第一个参数传入。

      2、绑定到类的方法:用classmethod装饰器装饰的方法,是一种为类量身定制的方法。

        使用方法:类名.boud_method(),自动将类当作第一个参数传入(对象也可调用,但类仍被当作第一个参数自动传入)

        如:  

    #!/usr/bin/env python3
    #-*- coding:utf-8 -*-
    
    class Func:
        def __init__(self,name):
            self.name = name
    
        @classmethod  # 绑定到类的方法,一般由类调用
        def func1(cls):
            print(cls,"类调用")
    Func.func1() #输出: <class '__main__.Func'> 类调用

    obj = Func.func1() # 实例化对象
    obj.func1() # 对象也可调用,但是默认传的参数仍然是类

      3、绑定到对象的方法:没有被任何装饰器修施的方法,为对象量身定制。

        使用方法:对象.boud_method() ,自动将对象当作第一个参数传入

        如:

    #!/usr/bin/env python3
    #-*- coding:utf-8 -*-
    
    class Func:
        def __init__(self,name):
            self.name = name
    
        def tell(self) # 绑定到对象的方法,仅由对象来调用
        print("姓名是:%s,由对象%f调用"%self.name)
    func = Func('cc') # 实例化一个对象
    func.tell() # 输出:姓名是cc,由对象调用
    # Func.tell() # 类调用时报错,故绑定到对象的方法只能由对象来调用

    三、非绑定方法

      1、定义:不与类或对象绑定,类和对象都可以调用,但是没有自动传值一说,简言之,非绑定方法就是一个普通工具。

        注意:要与绑定到对象方法区分开,在类中直接定义的函数,没有被任何装饰器修饰的,就是绑定到对象的方法,不是普通函数,能够自动传值;而staticmethod装饰的方法,任谁调用,都没有自动传值。

      2、使用方法:对象/类.method(),全部参数都需要手动传入

        如:

    #!/usr/bin/env python3
    #-*- coding:utf-8 -*-
    
    class Func:
        def __init__(self):
            self.name = name
    
        @staticmethod # 非绑定方法,类和对象均可带调用,无自动传值
        def func2(a,b):
            print('类或对象均可',a+b)

    func.func2(5,6) # 输出:11 类与对象均可
    Func.func2(4,7) # 输出:11 类与对象均可

    四、classmethod 和 staticmethod 的对比

    # settings.py
    
    name = 'cc'
    age = 21
    male = 'male'
    DB_PATH = 'D:pycharmTest1Thrid_module面向对象编程
    # test.py
    import settings
    
    import settings
    class Introduce:
        def __init__(self,name,age):
            self.name = name
            self.age = age
        @staticmethod
        def intro_yourself():
            return Introduce(settings.name,settings.age)
    
        @classmethod # 哪个类来调用,就将那个类当作第一个参数传入
        def tell_others(cls):
            return cls(settings.name,settings.age)
    
        def __str__(self):
            return 'Your power is not enough!'
    
    class Test(Introduce):
            def __str__(self):
                return '<%s,%s>'%(self.name,self,age)
    
    per1 = Test.intro_yourself() 
    print(per1) # 输出:Your power is not enough! # 原本想触发Test.__str__执行,但结果是触发了Introduce.__str__的执行。
    
    per2 = Test.tell_others()
    print(per2) # 输出: <cc,21>

    五、三种方法的综合使用

    class People:
        def __init__(self,name,age,sex):
            self.id = self.set_id()
            self.name = name
            self.age = age
            self.sex = sex
        def tell_info(self): # 绑定到对象的方法
            print('姓名:%s' '年龄:%s' '性别:%s'%(self.name, self.age, self.sex))
    
        @classmethod  # 绑定到类的方法
        def from_class(cls):
            obj = cls(
                settings.name,
                settings.age,
                settings.sex
            )
            return obj
    
        @staticmethod  # 静态方法,非绑定方法
        def set_id():
            m = hashlib.md5(str(time.time()).encode('utf-8'))
            return m.hexdigest()
    
    #p = People('sc',20,'male')
    # 绑定到对象,就应该由对象来调用,自动将对象本身当作第一个参数传入
    #p.tell_info() #姓名:sc年龄:20性别:male
    
    # 绑定给类,就应该由类来调用,自动将类本身当作第一个参数传入
    #p = People.from_class() # 等同于People.from_class(People)
    #print(p.tell_info()) # 姓名:cc年龄:21性别:male
    
    # 非绑定方法,不与类或对象绑定,谁都可以调用,没有自动传值一说
    p1 = People('sc1',20,'male')
    p2 = People('SC2',21,'MALE')
    p3 = People('Sc3',22,'Male')

    六、绑定方法与非绑定方法的练习

      要求:      

    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方法用来从文件中反序列化出对象。

    #settings.py
    HOST = '127.0.0.1'
    PORT = 3302
    DB_PATH = 'D:pycharmTest1Thrid_module面向对象编程Testdb'
    
    # test.py
    import settings
    import  hashlib
    import time
    import os
    import pickle
    
    class Mysql:
        def __init__(self,host,port):
            self.id = self.creat_id()
            self.host = host
            self.port = port
        @staticmethod
        def creat_id():
            m = hashlib.md5(str(time.time()).encode('utf-8'))
            return m.hexdigest()
    
        def save(self):
            '''自动将对象序列化到文件中,路径为DB_PATH,文件名为id号'''
            try:
                 if not isinstance(self,str):
                     with open(os.path.join(settings.DB_PATH,self.id),'wb') as f:
                         pickle.dump(self,f)
            except Exception as e:
                print('error',e)
    
        def get_obj_by_id(self):
            try:
                if os.path.isfile(os.path.join(settings.DB_PATH,self.id)):
                    with open(os.path.join(settings.DB_PATH,self.id),'rb') as f:
                        data =  pickle.load(self,f)
                        return data
            except Exception as e:
                print('error',e)
    
        def bound1(self):
            return Mysql(self.host,self.port)
    
        @classmethod
        def bound2(cls):
            return cls(settings.Host,settings.PORT)
    
    
    obj1 = Mysql('127.0.0.1',6666)
    print(obj1)
    obj2 = Mysql.creat_id()
    print(obj2)
    View Code
  • 相关阅读:
    基本数据类型相互转换及操作方法
    python以及计算机原理基础简要摘录
    Linux程序包管理
    rpm命令详解
    Linux程序包管理
    Linux任务计划
    压缩,解压缩工具及bash脚本编程
    btrfs文件系统管理与应用
    LVM应用
    CSS核心技术
  • 原文地址:https://www.cnblogs.com/schut/p/8640110.html
Copyright © 2011-2022 走看看