• 面向对象基础


    面向对象编程(Object Oriented Programming,OOP)

    1. 面向过程编程最易被初学者接受,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,即:将之前实现的代码块复制到现需功能处。
    2. Java和C#只支持面向对象编程,而python比较灵活,即支持面向对象编程也支持函数式编程。
    3. 面向对象三大特性:封装继承多态

    一、封装

    封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容。
    调用被封装的内容时,有两种情况:

    1. 通过对象直接调用
    2. 通过self间接调用
    #1. 通过对象直接调用
    class Foo:
        def __init__(self, name, age):
            self.name = name
            self.age = age
     
    obj1 = Foo('morra', 18)
    print obj1.name    # 直接调用obj1对象的name属性
    print obj1.age     # 直接调用obj1对象的age属性
     
    
    #2. 通过self间接调用
    class Foo:
        def __init__(self, name, age):
            self.name = name
            self.age = age
      
        def detail(self):
            print self.name
            print self.age
      
    obj1 = Foo('morra', 18)
    obj1.detail()  # Python默认会将obj1传给self参数,所以,此时方法内部的 self = obj1
     
    

    综上所述,对于面向对象的封装来说,其实就是使用__init__方法将内容封装到对象中,然后通过对象直接或者self间接获取被封装的内容。

    二、继承

    继承,就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法。父类也叫基类,子类也叫派生类。

    class Animals:              #基类
        def __init__(self, name):
            self.name = name
     
        def eat(self):
            pass
     
        def drink(self):
            pass
     
    class Dog(Animals):         #派生类
        def __init__(self, name):
            self.name = name
     
        def bark(self):
            print('汪')
     
     
    obj_dog = Dog('morra')
    obj_dog.eat()
    obj_dog.bark()
    

    (1) 单继承

    优先级是,先子类后父类

    (2) 多继承

    python可以同时继承多个类(C# java是不可以的)。
    优先级是,先子类后父类,父类里面先左再右,广度优先。

    #新式类的广度优先查找
    class D(object):
        def bar1(self):
            print 'D.bar'
     
    class C(D):
        def bar(self):
            print 'C.bar'
     
    class B(D):
        def bar(self):
            print 'B.bar'
     
    class A(B, C):
        def bar(self):
            print 'A.bar'
    a = A()
    # 执行bar方法时
    # 查找顺序:A --> B --> C --> D
    # 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
    a.bar()
    

    (3) 执行父类的构造方法

    #方法一:super,通过python多继承的原则查找
    class Animal:
        def __init__(self):
            print('A构造方法')
            self.ty = "动物"
     
    class Cat(Animal):
        def __init__(self):
            print('B构造方法')
            self.n = "猫"
            super(Cat,self).__init__()  #执行父类的构造方法,推荐用super()
     
    c = Cat()
    print(c.__dict__)
     
    # ---------
    # B构造方法
    # A构造方法
    # {'n': '猫', 'ty': '动物'}
     
     
    #方法二:Animal,直接指定基类(不建议使用)
    class Animal:
        def __init__(self):
            print('A构造方法')
            self.ty = "动物"
     
    class Cat(Animal):
        def __init__(self):
            print('B构造方法')
            self.n = "猫"
            Animal.__init__(self)       #不推荐
     
    c = Cat()
    print(c.__dict__)
     
    # ---------
    # B构造方法
    # A构造方法
    # {'n': '猫', 'ty': '动物'}
    

    三、多态

    Pyhon不支持Java和C#这一类强类型语言中多态的写法,但是原生多态,其Python崇尚“鸭子类型”。

    python的“鸭子类型”:

    class F1:
        pass
     
    class S1(F1):
        def show(self):
            print 'S1.show'
     
    class S2(F1):
        def show(self):
            print 'S2.show'
     
    def Func(obj):
        print obj.show()
     
    s1_obj = S1()
    Func(s1_obj) 
     
    s2_obj = S2()
    Func(s2_obj) 
    

    四、反射在面向对象里的应用

    class Foo:
        def __init__(self,name):
            self.name = name    对象.属性=变量
            pass
     
        def show(self):
            pass
     
     
    obj = Foo('morra')
     
    r = hasattr(Foo, 'show')    #只能找类里的成员
    print(r)  # True
     
    r = hasattr(obj, 'name')   #在对象中可以找自己的属性,就是self.name中的name属性
    print(r)  # True
     
    r = hasattr(obj, 'show')    #对象中也可以找类的成员,是通过python里的类对象指针来实现的
    print(r)  # True
     
    

    m = __import__('s1',fromlist=True)      #通过反射获取模块
     
    class_name = getattr(m,"Foo")       #在模块中获取Foo类
     
    obj = class_name('morra')       #实例化
     
    val = getattr(obj,'name')         #获取类中的name属性
     
    print(val)
    

    五、旧式类与新式类

    旧式类与新式类区别总结:

    1. 在python2.x的版本才有新式类和旧式类之分
    2. 新式类的存在是为了统一类(class)和类型(type)
    3. 旧式类定义class AA,新式类class AA(object)
    4. 在多重继承的查找和调用方法上,旧式类是深度优先,新式类是广度优先
    5. 在python2.x版本中为了确保自己使用的是新式类,有以下方法:
      (a)_metaclass_ = type
      (b)自己的类都从内建类object直接或者间接地继承
    6. 在Python3里面,不存在这些问题了,因为所有的类都是object类的子类(隐式),python3中都是新式类,即使用广度优先的查找方法

    (1) 定义形式

    #python2.7中的旧式类
    class AA():
        pass
     
    a = AA()
    print(type(a))      #<type 'instance'>
    print(type(AA))     #<type 'classobj'>
     
     
    #python2.7中的新式类
    class AA(object):
        pass
     
    a = AA()
    print(type(a))      #<class '__main__.AA'>
    print(type(AA))     #<type 'type'>
     
     
    #python3中的新式类
    class AA(object):
        pass
     
    a = AA()
    print(type(a))      ## <class '__main__.AA'>
    print(type(AA))     # <class 'type'>
    

    (2) 多重继承时的查找规则

    #旧式类的深度优先查找
    class D:
        def bar1(self):
            print 'D.bar'
     
    class C(D):
        def bar(self):
            print 'C.bar'
     
    class B(D):
        def bar(self):
            print 'B.bar'
     
    class A(B, C):
        def bar(self):
            print 'A.bar'
     
    a = A()
    # 执行bar方法时
    # 查找顺序:A --> B --> D --> C
    # 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
    a.bar()
    

    #新式类的广度优先查找
    class D(object):
        def bar1(self):
            print 'D.bar'
     
    class C(D):
        def bar(self):
            print 'C.bar'
     
    class B(D):
        def bar(self):
            print 'B.bar'
     
    class A(B, C):
        def bar(self):
            print 'A.bar'
    a = A()
    # 执行bar方法时
    # 查找顺序:A --> B --> C --> D
    # 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
    a.bar()
    

    六、补充

    (1) isinstance(obj, cls)

    检查是否obj是否是类 cls 的对象

    class Foo(object):
        pass
     
    obj = Foo()
    
    isinstance(obj, Foo)
    

    (2) issubclass(sub, super)

    检查sub类是否是 super 类的派生类

    class Foo(object):
        pass
     
    class Bar(Foo):
        pass
     
    issubclass(Bar, Foo)
    

    (3) __base__父类查询

    用 _base_ 属性来查询某个类的父类

    class father:
        pass
    
    class child(father):
        pass
    print(father)   #<class '__main__.father'>
    print(child.__base__)   #<class '__main__.father'>
    

    (4) __class__查询对象所属的类和类名

    a = [1, 2, 3]
    print(a.__class__)  #<class 'list'>,查询对象所属的类
    print(type(a))      #<class 'list'>
    
    print(a.__class__.__name__)     #list,查询对象所属类的类名
    

    (5) 查询对象的属性

    除了使用dir()来查询对象的属性之外,我们可以使用下面内置(built-in)函数来确认一个对象是否具有某个属性:

    hasattr(obj, attr_name)   # attr_name是一个字符串
    

    例如:

    a = [1,2,3]
    print(hasattr(a,'append')) 
    

    (6) 查询函数的参数

    import inspect
    print(inspect.getargspec(func))
    
  • 相关阅读:
    【硬件设备】海康NVR硬盘录像机接入海康RTSP摄像头操作步骤
    互联网直播服务中域名与IP有什么关系?TSINGSEE青犀视频全线产品的应用全解
    H.265编码视频播放器EasyPlayerPro for Windows使用FFMPEG编码过程说明
    RTSP/GB28181/HIKSDK/Ehome协议视频平台EasyCVR如何通过ffmpeg 将 H.264 I帧数据转换为 BGR 数据?
    如何轻松搞定内网摄像头远程运维?EasyNTS上云网关简单三步实现设备公网远程控制、远程配置
    RTSP/GB28181/HIKSDK/Ehome协议视频平台EasyCVR使用OpenCV 从内存中构建 Mat 数据说明
    视频上云服务平台EasyCVR使用Go语言可执行程序出现“Process XXX has exited with status XXXX”错误
    视频智能分析/视频上云服务平台EasyCVR通过GB28181级联后RTSP协议视频流无法播放问题排查
    网络摄像头无插件直播H265编码视频播放器EasyPlayer网页播放器不能播放怎么处理?
    JSP中session对象的理解
  • 原文地址:https://www.cnblogs.com/whatisfantasy/p/6037060.html
Copyright © 2020-2023  润新知