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。。 有一种默契叫做我不理你,你就不理我

  • 相关阅读:
    安卓虚拟机adb shell sqlite3数据库
    gridview安卓实现单行多列横向滚动
    安卓gridview 网格,多行多列实现
    安卓5.0 沉浸式状态栏
    Acionbar logo
    .replace(R.id.container, new User()).commit();/The method replace(int, Fragment) in the type FragmentTransaction is not app
    导航抽屉图标+文字
    透明ActionBar
    去掉Actionbar下的shadow
    沉浸式导航栏
  • 原文地址:https://www.cnblogs.com/weidaijie/p/10480256.html
Copyright © 2011-2022 走看看