zoukankan      html  css  js  c++  java
  • 假期(面向对象相关)

    """
    一、isinstance(obj,cls) 和 issubclass(sub,super)
        isinstance(obj,cls) 检查obj是否是类cls的对象
            class Bar(object):
                pass
            class Foo(object):
                pass
            obj = Foo()
            print(isinstance(obj,Foo))     #True
            print(isinstance(obj,Bar))     #False
        issubclass(sub,super) 检查sub类是否是super类的子类(派生类)
            class Bar(object):
                pass
            class Foo(Bar):
                pass
            class Te(object):
                pass
            print(issubclass(Foo,Bar))    #True
            print(issubclass(Te,Bar))     #False
    """
    """
    二、反射:通过字符串的方式操作对象相关的属性,python中的一切事物都是对象,都可以使用反射
        hasattr(object,name) 判断object中有没有一个name字符串对应的方法或者是属性
        getattr(object,name,default=None)  从object中获取name属性,如果没有返回默认值None
        setattr(obj,x,y) 给obj对象设置属性x=y
        delattr(obj,x) 删除对象obj里的x属性
        类也是对象,也可以有这四个方法
        使用方法测试:
            class Foo(object):
                name = "我是你的什么啊?"
                def __init__(self,addr):
                    self.addr = addr
            obj = Foo("去你大爷的")
            print(hasattr(obj,"name"))    #True
            print(getattr(obj,"name"))    #我是你的什么啊?
            setattr(obj,"sb",True)
            print(obj.__dict__)           #{'addr': '去你大爷的', 'sb': True}
            delattr(obj,"sb")
            print(obj.__dict__)           #{'addr': '去你大爷的'}
            反射当前模块成员:
                import sys
                def s1():
                    print("s1")
                def s2():
                    print("s2")
                this_module = sys.modules[__name__]
                print(hasattr(this_module,"s1"))
        使用反射的好处:
            实现代码的可插拔机制;在导入模块方面经常使用反射;动态的导入模块
            
    三、__setattr__,__delattr__,__getattr__;
        #__setattr__添加/修改属性会触发它的执行
        #__delattr__删除属性的时候会触发
        #__getattr__只有在使用点调用属性且属性不存在的时候才会触发
    
    四、二次加工标准类型(包装)
        class List(list): #继承list所有的属性,也可以派生出自己新的,比如append和mid
        def append(self, p_object):
            ' 派生自己的append:加上类型检查'
            if not isinstance(p_object,int):
                raise TypeError('must be int')
            super().append(p_object)        #调用父类的append方法
        @property
        def mid(self):
            '新增自己的属性'
            index=len(self)//2
            return self[index]
        实现授权的关键点就是覆盖__getattr__方法
        import time
        class FileHandle:
            def __init__(self,filename,mode='r',encoding='utf-8'):
                self.file=open(filename,mode,encoding=encoding)
            def write(self,line):
                t=time.strftime('%Y-%m-%d %T')
                self.file.write('%s %s' %(t,line))
        
            def __getattr__(self, item):
                return getattr(self.file,item)
        
        f1=FileHandle('b.txt','w+')
        f1.write('你好啊')
        f1.seek(0)
        print(f1.read())
        f1.close()
            
    五、__getattribute__:        
        和__getattr__类似,不过不管是否存在都会执行
        class Foo:
            def __init__(self,x):
                self.x = x
            def __getattribute__(self, item):
                print("我总会执行")
        obj = Foo(10)
        print(obj.x)
        print(obj.xxx)
        !当getattr和getattribute同事存在的时候只执行getattribute,除非抛出异常,两者一起执行
        
    六、描述符(__get__,__set__,__delete__):
        什么是描述符:描述符的本质就是一个新式类,在这个新式类中至少实现了__get__(),__set__(),__delete__()中的一个
                    这也被称为描述符协议
        __get__():调用一个属性的时候触发
        __set__():为一个属性赋值的时候触发
        __delete__():删除属性的时候触发
            class Foo:   #这个类称为描述符
                def __get__(self, instance, owner):
                    pass
                def __set__(self, instance, value):
                    pass
                def __delete__(self, instance):
                    pass
        描述符的作用:用来代理另外一个类的属性(必须把描述符定义为这个类的类属性,不能定义到构造方法中)
        分类:
            数据描述符:至少实现了__get__() 和__set__()方法
            非数据描述符:没有实现__set__()方法
        注意事项:
            1、描述符本身应该定义为新式类,被代理的类也应该是新式类
            2、必须定义为类属性,不能定义到构造函数中
            3、要严格遵循优先级,优先级由高到低分别是(类属性,数据描述符,实例属性,非数据描述符,找不到的时候触发__getattr__())
        描述符的使用:
        描述符的总结:
        
    六、property:
        一个静态属性property本质就实现了get,set,delete三种方法
        用法一:
            class Foo:
                @property
                def AAA(self):
                    print("get的时候运行")
                @AAA.setter
                def AAA(self,value):
                    print("set的时候运行",value)
                @AAA.deleter
                def AAA(self):
                    print("delete 的时候运行")
            obj = Foo()
            obj.AAA  #get
            obj.AAA = "aaa"   #set
            del obj.AAA    #delete
        用法二:
            class Foo:
                def get_AAA(self):
                    print("get的时候yunx")
                def set_AAA(self,value):
                    print("set 的时候运行")
                def delete_AAA(self):
                    print("delete的时候运行")
                AAA=property(get_AAA,set_AAA,delete_AAA)    #内置的property三个参数必须与get,set,delete一一对应
    
    七、__setitem__,__getitem__,__delitem__:
        示例代码;
            class Foo:
                def __init__(self,name):
                    self.name = name
                def __getitem__(self, item):
                    print(self.__dict__[item])
                def __setitem__(self, key, value):
                    self.__dict__[key] = value
                def __delitem__(self, key):
                    print("del obj 时执行")
                def __delattr__(self, item):
                    print("del obj 执行,")
                    self.__dict__.pop(item)
            obj = Foo("sb")
            obj["age"] = 18
            obj["age1"] = 19
            del obj.age1
            del obj["age"]
            obj["name"] = "alex"
            print(obj.__dict__)
            
    八、__str__,__repr__,__format__:
        改变对象的字符串显示__str__,__repr__,当你打印对象的时候假如里面没有这两个方法,那么打印出来的你是看不懂的
        自定义格式化字符串:__format__    
            str函数或者print函数--->obj.__str__()
            repr或者交互式解释器--->obj.__repr__()
            如果__str__没有被定义,那么就会使用__repr__来代替输出
            注意:这俩方法的返回值必须是字符串,否则抛出异常    
                - 示例:
                format_dict={
                    'nat':'{obj.name}-{obj.addr}-{obj.type}',#学校名-学校地址-学校类型
                    'tna':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址
                    'tan':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名
                }
                class School:
                    def __init__(self,name,addr,type):
                        self.name=name
                        self.addr=addr
                        self.type=type
                
                    def __repr__(self):
                        return 'School(%s,%s)' %(self.name,self.addr)
                    def __str__(self):
                        return '(%s,%s)' %(self.name,self.addr)
                
                    def __format__(self, format_spec):
                        if not format_spec or format_spec not in format_dict:
                            format_spec='nat'
                        fmt=format_dict[format_spec]
                        return fmt.format(obj=self)
                s1=School('oldboy1','北京','私立')
                print('from repr: ',repr(s1))
                print('from str: ',str(s1))
                print(s1)
                
                print(format(s1,'nat'))
                print(format(s1,'tna'))
                print(format(s1,'tan'))
                print(format(s1,'asfdasdffd'))    
            
    九、__slots__:
        在类中写一个slots,在吧类中的某些字段写在里面,外部才可以访问,不写访问不到
        
    十、__next__和__iter__实现迭代器协议    
        模拟实现range方法:
            class Range:
                def __init__(self,n,stop,step):
                    self.n=n
                    self.stop=stop
                    self.step=step
            
                def __next__(self):
                    if self.n >= self.stop:
                        raise StopIteration
                    x=self.n
                    self.n+=self.step
                    return x
            
                def __iter__(self):
                    return self
            
            for i in Range(1,7,3): #
                print(i)
            
    十一、__doc__
        - 显示描述信息,即注释信息
        - 无法被继承
    
    十二、__module__和__class__
        - __module__  表示当前操作的对象在哪个摸快
        - __class__表示当前操作的对象的类是什么
        
    十三、__del__:
        - 析构方法:当对象在内存中被释放时执行这段代码
        - 比如在数据库链接中关闭数据库,文件操作中的close操作
        
    十四、__enter__和__exit__:
        __enter__在进来的时候执行
        __exit__在出去的时候执行
            - 对象调用前后执行这两个方法
            
    十五、__call__方法:
        - 对象后边+括号自动触发执行
        - 构造方法的执行是由创建对象触发的,即对象=类名();而对于__call__方法是对象()或者类()()
        
    十六、metaclass
        exec:三个参数       字符串形式的命令  全局作用域  局部作用域
        exec会在指定的局部作用域内执行字符串内的代码,除非明确地使用global关键字
        - 类也是对象
        - 什么是元类
            - 元类是类的类,类的模板
            - 元类是用来控制如何创建类的,正如类是创建对象的模板一样,而元类的主要目的是为了控制类的创建行为元类的实例化的结
              果为我们用class定义的类,正如类的实例为对象(f1对象是Foo类的一个实例,Foo类是 type 类的一个实例)type是python的一
              个内建元类,用来直接控制生成类,python中任何class定义的类其实都是type类实例化的对象
        - 创建类的两张方式:
            - 方式一:使用class关键字
            - 方式二:手动模拟class创建类的过程
                - 类名
                - 类的父类
                - 类体
                    #类名
                    class_name='Chinese'
                    #类的父类
                    class_bases=(object,)
                    #类体
                    class_body=
                    country='China'
                    "
                    def __init__(self,name,age):
                        self.name=name
                        self.age=age
                    def talk(self):
                        print('%s is talking' %self.name)
                    "
        - 一个类没有声明自己的元类,默认它的元类就是type,除了使用元类type,用户也可以通过继承type俩自定义元类
        - #元类控制类的实例化过程:
                1 类(),调用元类.__call__()
                2 在1的方法中调用:
                    类.__new__() #返回类的对象obj
                    类.__init__(obj,...) #为对象进行初始化
                
        - 元类控制类本身的产生过程
        
            
        
        
        
    """
  • 相关阅读:
    div在IOS系统和安卓系统位置不同
    js操作样式
    Css设置文字旋转
    textarea高度自适应
    html引入html页面
    举例说明$POST 、$HTTP_RAW_POST_DATA、php://input三者之间的区别
    PHP获取POST的几种方法
    PHP以xml形式获取POST数据
    使用Composer安装Symfony
    php如何以post形式发送xm并返回xmll数据
  • 原文地址:https://www.cnblogs.com/52-qq/p/8448140.html
Copyright © 2011-2022 走看看