• 面向对象 --- 类的绑定方法,面向对象高阶


    昨日回顾

    类的绑定方法

    classmethod(类的绑定方法)

    翻译过来是一个类方法,是一个装饰器,可以装饰给类内部的方法,使该方法绑定给类来使用。

    --- 对象的绑定方法的特殊之处:由对象来调用,会将对象当作第一个参数传给该方法

    --- 类的绑定方法的特殊之处:由类来调用,会将类仿作第一个参数传给该方法

    通过对象也可以调用,只是默认传递的第一个参数还是这个对象对应的类

    staticmethod(非绑定方法)

    是一个装饰器,可以装饰类内部的方法,使该方法即不绑定给对象,也不绑定给类。谁都可以调用,且没有自动传值的效果

    简而言之,非绑定方法就是将普通方法放到类的内部

    总结

    如果函数体代码需要用外部传入的类,则应该将函数定义成绑定给类的方法

    如果函数体代码需要用外部传入的对象,则应该将函数定义成绑定给对象的方法

    如果函数体代码即不需要外部传入的类,也不需要外部传入的对象,则应该将该函数定义成非绑定方法/普通函数

    面向对象高阶

    isinstance

    python内置的函数,用来传入两个参数,用于判断参数1是否是参数2的一个实例。

    判断一个对象是否使一个类的实例,打印结果使True或者使False

    print(isinstance(obj,class))
    

    issubclass

    python内置的函数,可以传入两个的参数,用于判断参数1是否使参数2 的子类。

    判断一个类是否是另一个类的子类,打印结果使True或者使False

    print(issubclass(子类,父类))
    

    反射(*******************)

    反射指的是通过 ’字符‘串’ 对 对象或者类的属性进行操作

    -- hasattr:通过字符串,判断该字符串是否使对象或类的属性

    print(hasattr(对象或者类,'属性'))
    

    -- getattr:通过字符串,获取对象或类的属性

    print(getattr(o,name,default))
    

    -- setattr:通过字符串,设置对象或类的属性

    setattr(p,'sal','3.0')
    print(hasattr(p,'sal'))    # True
    

    -- delattr:通过字符串,删除对象或类的属性。

    delattr(p,'sal')
    print(hasattr(p,'sal'))
    

    魔法方法(类的内置方法)

    凡是在类内部定义,以"__开头__结尾"的方法都称之为魔法方法,又称“类的内置方法”。

    魔法方法会在某些条件成立时触发。

    __str__:在打印对象时触发

    __def__:对象被销毁前执行该方法,该方法会在最后执行

    __getattr__:会在对象.属性时,“属性没有”的情况下才会触发

    __setattr__:会咋“对象.属性 = 属性值”时触发

    __call__:会砸对象你被调用时触发

    __new__:会在__init__执行前触发

    __init__:在调用类时触发

    关于对__new__与__init__的理解在定义的类中,__new__是自动运行的,而且是隐藏起来的,当调用类进行实例化的时候,__new__与__init__一样是自动运行的,但是区别是__new__运行之后是产生一个空的对象的名称空间,然后__init__的作用是对这个产生的空的名称空间进行修饰。__new__后边跟的是(cls),指的是类,在执行的时候,传入的第一个对象是类,而__init__后边跟着的是(self),指的是对象,在执行的时候传入的第一个对象是对象本身。所以在运行 __init__的时候,其实是运行了__new___和__init__,一个负责搭建空的对象的名称空间,一个负责对这个空的名称空间进行装饰,也就是将__init__中的参数值添加到所产生的名称空间内。然而,当自己定义一个__new__的时候,会先执行自己定义的这个__new__,但是记住一定要记住最后一步一定要返回  object.__new__(cls),作用是来调用来调用object类中的__new__来产生一个空的名称空间,不然下边的__init__没有办法执行来对空的对象的名称空间进行修饰,因为就没有产生对象的名称空间.
    
    class Foo(object):
    
        #
        def __new__(cls, *args, **kwargs):
            return object.__new__(cls)  # 真正产生一个空对象
    
        # 若当前类的__new__没有return一个空对象时,则不会触发。
        def __init__(self):
            print('在调用类时触发...')
    
        def __str__(self):
            print('会在打印对象时触发...')
            # 必须要有一个返回值, 该返回值必须时字符串类型
            return '[1, 2, 3]'
    
        def __del__(self):
            print('对象被销毁前执行该方法...')
    
        def __getattr__(self, item):
            print('会在对象.属性时,“属性没有”的情况下才会触发...')
            print(item)
            # 默认返回None, 若想打印属性的结果,必须return一个值
            return 111
    
        # 注意: 执行该方法时,外部“对象.属性=属性值”时无效。
        def __setattr__(self, key, value):
            print('会在 “对象.属性 = 属性值” 时触发...')
            print(key, value)
            print(type(self))
            print(self, 111)
            self.__dict__[key] = value
    
        def __call__(self, *args, **kwargs):
            print(self)
            print('调用对象时触发该方法...')
    #
    foo_obj = Foo()
    print(foo_obj)
    print(foo_obj.x)
    print(foo_obj.x)
    foo_obj.x = 123
    print(foo_obj.x)
    foo_obj()
    

    单例模式

    在类中,在调用一次类,就会进行一次类的实例化,就会产生一个对象的名称空间,再次调用的时候,会继续产生新的名称空间,在调用相同的文件的时候也是会产生不同的名称空间,这样的话比较浪费内存,所以就想对同一个文件打开的时候,对应的名称空间是同一个,方法如下:

    class File:
    
        __instance = None
    
        # 单例方式1:
        # @classmethod
        # def singleton(cls, file_name):
        #     if not cls.__instance:
        #         obj = cls(file_name)
        #         cls.__instance = obj
        #     return cls.__instance
    
        # 单例方式2:
        def __new__(cls, *args, **kwargs):
            # cls.__new__(cls, *args, **kwargs)
            if not cls.__instance:
                cls.__instance = object.__new__(cls)
                print(cls.__instance)
            return cls.__instance
    
        def __init__(self, file_name, mode='r', encoding='utf-8'):
            self.file_name = file_name
            self.mode = mode
            self.encoding = encoding
    
        def open(self):
            self.f = open(self.file_name, self.mode, encoding=self.encoding)
    
        def read(self):
            res = self.f.read()
            print(res)
    
        def close(self):
            self.f.close()
    
    
    # 方式1:
    # obj1 = File.singleton('jason雨后的小故事.txt')  # singleton(cls)
    # obj2 = File.singleton('jason雨后的小故事.txt')  # singleton(cls)
    # obj3 = File.singleton('jason雨后的小故事.txt')  # singleton(cls)
    # obj1 = File('jason雨后的小故事.txt')
    # obj2 = File('jason雨后的小故事.txt')
    # obj3 = File('jason雨后的小故事.txt')
    # print(obj1)
    # print(obj2)
    # print(obj3)
    
    # 方式2:
    obj1 = File('jason雨后的小故事.txt')  # singleton(cls)
    obj2 = File('jason雨后的小故事.txt')  # singleton(cls)
    obj3 = File('jason雨后的小故事.txt')  # singleton(cls)
    print(obj1)
    print(obj2)
    print(obj3)
    
  • 相关阅读:
    Java SE 基础之接口回顾
    读书杂谈-《架构探险:从零开始写Java Web框架》
    Java Se之类加载问题思考
    struts2 下载记录
    《重构改善既有代码的设计》笔记之序
    Luence简单实现2
    RabbitMQ学习(1):安装
    jquery插件dataTables添加序号列
    父<IFRAME>获取子页属性以及子页中<IFRAME>的方法
    类的约束 异常处理 自定义异常 MD5 日志信息处理
  • 原文地址:https://www.cnblogs.com/whkzm/p/11663538.html
Copyright © 2020-2023  润新知