zoukankan      html  css  js  c++  java
  • 面向对象

    面向对象的三大特性:封装、继承、多态

    • 封装:

                 方法封装到类中

    class File:
        def file_add():pass
        def file_update():pass
        def file_del():pass
        def file_fetch():pas
    

         将数据封装到对象中

    class File:
        def __init__(self,name,age,email):
            self.name = name 
            self.age = age 
            self.email = email 
        def file_add():pass
        def file_update():pass
        def file_del():pass
        def file_fetch():pass
    
    obj1 = File('oldboy',19,"asdf@live.com")
    obj2 = File('oldboy1',119,"asdf12@live.com")
    

    应用:

      • -Flask上下文管理中把session/request封装到了RequestContex对象中
      • -app/g封装到了AppContext中
      • -restframework的Request(对数据的封装)
    • 继承

        如果多个类中有相同的方法,为了避免重复编写可以将其放在父类(基类)中

    class Base(object):
        def xxxx():pass
    class File(Base):
        def __init__(self,name,age,email):
            self.name = name 
            self.age = age 
            self.email = email 
        def file_add():pass
        def file_update():pass
        def file_del():pass
        def file_fetch():pass
    class DB(Base):
        def db_add():pass
        def db_update():pass
        def db_del():pass
        def db_fetch():pass
    

         应用:

    • 我印象最深的就是restframework的多继承
        
    • 多态

                 多态(鸭子模型):天生支持多态,对于参数来说可以传入任何类型的对象,只要保证有想要的send方法即可。

    class Msg(object):
        def send():
            pass 
    class WX(object):
        def send():
            pass 
    def func(arg):
        arg.send()
    

     进阶

    类里面常用的双下划线的方法

    __init__

    • 初始化操作

    __new__

    • 创建对象, 在实例化对象的时候会先触发__new__方法,创建对象,再触发__init__进行实例化
    • 应用
      • 单例模式
      • rest framework 序列化组件,判断many=True或者False触发创建不同的返回不同类的对象

    __call__

    • 对象()的时候触发__call__类的方法
    • 应用:
      • flask源码请求入口.一旦请求进来会触发实例化Flask的对象()
      • Django源码入口
    • __getattr__
      • 当对象.属性的时候会触发该方法
      • 应用:
        • Flask上下文管理中,LocalStack取值getattr()触发Local的__getattr__方法将想要的数据返回
        • restframework中获取配置文件信息的时候也是通过触发__getattr__方法获取
    • __setattr__
      • obj.xx=1 给对象的属性赋值的时候触发
      • 应用:
        • Flask上下文管理中在实例化Local对象的时候在__init__方法里执行了object.__setattr__(self, '__storage__', {})设置了一个空的字典
        • 还获取了object.__setattr__(self, '__ident_func__', get_ident)线程或者协程的唯一标识
    • __delattr__
    • __getitem__
      • 对象['xx'] 触发
      • 应用
        • 在取session['a1']的值的时候会触发该方法
        • 所有对象['x1']都会触发,需要自己定义才能够运行
    • __setitem__
      • 在对象['xxx']=1 触发
    • __delitem__
      • 删除 del 对象['触发']
    • __mro__
      • 查找继承顺序
      • 应用
        • 在wtforms源码中FormMeta在__call__方法中去找Meta类的时候使用了__mro__查看该类所有的继承顺序,然后用__dict__判断Meta是否在里面,在的话就放到一个列表中
    • __str__
      • 用于显示对象信息
      • 应用
        • 在Model中定义返回的数据格式可以在admin直观的看到
    • __repr__
    • __iter__
      • 让对象可以迭代
      • 应用  
        • Wtforms和Django的form组件都是用__iter__返回了一个迭代器,实例化对象后可以循环的渲染标签
    • __dict__
      • 应用
        • 对象将__init__字段以字典的形式传回,可以用于封装数据

    高级metaclass

    - 创建类时,先执行type的__init__。
    - 类的实例化时,执行type的__call__,__call__方法的的返回值就是实例化的对象。
       type的__call__方法内部调用:
    - 类.__new__,创建对象
    - 类.__init__,对象的初始化

    类创建的两种方式:

    #常用方式
    class Foo(object):
        a1 = 123
        def func(self):
            return 666
    
    #type方式
    Foo = type("Foo",(object,),{'a1':123,'func':lambda self:666}
    

     如何指定类由自定义type创建

    class MyType(type):
        pass 
    class Foo(object,metaclass=MyType):
        # __metaclass__ = MyType    # py2
        pass 
    Foo = MyType('Foo',(object,),{})
    

     默认执行顺序

    class Foo(object,metaclass=MyType):
        pass     
    obj = Foo()        
    class MyType(type):
        def __init__(self,*args,**kwargs):
            print('111')
            super(MyType,self).__init__(*args,**kwargs)
    class Base(object, metaclass=MyType):
        pass
    
    class Foo(Base):
        pass
    如果类自己或基类中指定了metaclass,那么该类就是由metaclass指定的type或mytype创建。
                        
    #同:
    class MyType(type):
        def __init__(self,*args,**kwargs):
            print('111')
            super(MyType,self).__init__(*args,**kwargs)
    
    
    # class Base(object, metaclass=MyType):
    #     pass
    
    Base = MyType('Base',(object,),{})
    
    class Foo(Base):
        pass
    #同:
    class MyType(type):
        def __init__(self,*args,**kwargs):
            print('111')
            super(MyType,self).__init__(*args,**kwargs)
    
    
    # class Base(object, metaclass=MyType):
    #     pass
    def with_metaclass(arg):
        Base = MyType('Base',(arg,),{})
        return Base
    
    class Foo(with_metaclass(object)):
        pass
    

    I can feel you forgetting me。。 有一种默契叫做我不理你,你就不理我

  • 相关阅读:
    LeetCode Best Time to Buy and Sell Stock
    LeetCode Scramble String
    LeetCode Search in Rotated Sorted Array II
    LeetCode Gas Station
    LeetCode Insertion Sort List
    LeetCode Maximal Rectangle
    Oracle procedure
    浏览器下载代码
    Shell check IP
    KVM- 存储池配置
  • 原文地址:https://www.cnblogs.com/weidaijie/p/10480256.html
Copyright © 2011-2022 走看看