• 面向对象编程


    面向对象编程

    面向对象的介绍

    面向对象的宗旨

    不写重复的代码

    代码易扩展,程序遵循易读,易改的原则

    面向对象的特性

    封装

    把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏

    继承

    通过继承创建的新类称为子类或派生类

    被继承的类称为基类,父类或超类

    继承的过程,就是一般到特殊的过程

    继承概念的实现方式有三类:

    • 实现继承:是指使用基类的属性和方法而无需额外编码的能力
    • 接口继承:是指使用属性和方法的名称,但是子类必须提供实现能力
    • 可视继承:是指子窗体(类)使用基窗体(类)的外观和实现代码的能力

    多态

          是允许将父对象设置成为一个或更多的他的子对象相等的技术,赋值之后,父对象可以根据当前赋值给它的子对象的特殊以不同的方式运作。简单说:允许将子类类型的指针赋值给父类类型的指针

     

    继承:

    class Animal:
    
        def eat(self):
            print "%s 吃 " %self.name
    
        def drink(self):
            print "%s 喝 " %self.name
    
        def shit(self):
            print "%s 拉 " %self.name
    
        def pee(self):
            print "%s 撒 " %self.name
    
    
    class Cat(Animal):   #继承Animal基类
    
        def __init__(self, name):
            self.name = name
            self.breed = '猫'
    
        def cry(self):
            print '喵喵叫'

     

    变量:

    变量包括:普通变量和静态变量,他们子定义和使用中有所区别,而最本质的区别是内存中保存的位置不同

    • 普通变量属于对象
    • 静态变量属于类
    class Province:
    
        # 静态变量
        country = '中国'
    
        def __init__(self, name):
    
            # 普通变量
            self.name = name
    
    
    # 直接访问普通变量
    obj = Province('河北省')
    print(obj.name)
    
    # 直接访问静态变量
    Province.country

     

    方法:

    包括普通方法,静态方法和类方法,在内存中都归属于类,区别在于调用方式不同。

    • 普通方法:由对象调用;至少一个self参数,执行普通方法时,自动将该方法的对象赋值给self
    • 类的方法:由类的调用;至少一个cls参数;执行类方法时,自动将调用该方法的类复制给cls
    • 静态方法:由类调用;无默认参数
    class Foo:
    
        def __init__(self, name):
            self.name = name
    
        def ord_func(self):
            """ 定义普通方法,至少有一个self参数 """
    
            # print self.name
            print( '普通方法')
    
        @classmethod
        def class_func(cls):
            """ 定义类方法,至少有一个cls参数 """
    
            print( '类方法')
    
        @staticmethod
        def static_func():
            """ 定义静态方法 ,无默认参数"""
    
            print( '静态方法')
    
    
    # 调用普通方法
    f = Foo()
    f.ord_func()
    
    # 调用类方法
    Foo.class_func()
    
    # 调用静态方法
    Foo.static_func()

    相同点:对于所有的方法,均属于类(非对象)中,所以在内存中也只保存一份

    不同点:方法调用者不同,调用方法时自动传入的参数不同

    属性:

    属性是普通方法的变种

    属性的基本使用:

    # ############### 定义 ###############
    class Foo:
    
        def func(self):
            pass
    
        # 定义属性
        @property
        def prop(self):
            pass
    # ############### 调用 ###############
    foo_obj = Foo()
    
    foo_obj.func()
    foo_obj.prop   #调用属性

    属性的定义和调用要注意以下几点:

    • 定义时,在普通方法的基础上添加@property装饰器
    • 定义时,属性仅有一个self参数
    • 调用时,无需括号    方法:foo_obj.fun()    属性:foo_obj.fun

    注意:属性存在的意义是:访问属性时可以制造出和访问变量完全相同的假象

              属性由方法变种而来,如果python中没有属性,方法完全可以代替其功能

    实例:对于主机列表页面,每次请求不可能把数据库中的所有内容都显示到页面上,而是通过分页的功能局部显示,所以在向数据库中请求数据时就要显示指定获取从第m到第n条的所有数据(即:limit m,n),这个分页的功能包括:

    • 根据用户请求的当前页面和总数据条数计算出m和n
    • 根据m 和n去数据库中请求数据
    # ############### 定义 ###############
    class Pager:
        
        def __init__(self, current_page):
            # 用户当前请求的页码(第一页、第二页...)
            self.current_page = current_page
            # 每页默认显示10条数据
            self.per_items = 10 
    
    
        @property
        def start(self):
            val = (self.current_page - 1) * self.per_items
            return val
    
        @property
        def end(self):
            val = self.current_page * self.per_items
            return val
    
    # ############### 调用 ###############
    
    p = Pager(1)
    p.start 就是起始值,即:m
    p.end   就是结束值,即:n

    python的属性的功能是:属性内部进行一系列的逻辑计算,最终将计算结果返回

    属性的两种定义方式:

    • 装饰器    在方法上应用装饰器
    • 静态字段  在类中定义值为property对象的静态字段

    装饰器方法:在类的普通方法上应用@property装饰器

    # ############### 定义 ###############
    class Goods(object):
    
        @property
        def price(self):
            print( '@property')
    
        @price.setter
        def price(self, value):
            print( '@price.setter')
    
        @price.deleter
        def price(self):
            print ('@price.deleter')
    
    # ############### 调用 ###############
    obj = Goods()
    
    obj.price          # 自动执行 @property 修饰的 price 方法,并获取方法的返回值
    
    obj.price = 123    # 自动执行 @price.setter 修饰的 price 方法,并将  123 赋值给方法的参数
    
    del obj.price      # 自动执行 @price.deleter 修饰的 price 方法

    属性有三种访问方式,并分别对应了三个被@property,@方法名.setter,@方法名.deleter装饰的方法,分别代表获取,修改,删除

     

     

    静态字段方式:创建值为property对象的静态字段

    property的构造方法中有四个参数

    • 第一个参数是方法名,调用 对象.属性 时自动触发执行方法
    • 第二个参数是方法名,调用 对象.属性 == XXX 时自动触发执行方法
    • 第三个参数是方法名,调用的 del 对象.属性 时自动触发执行方法
    • 第四个参数是字符串,调用 对象.属性.__doc__ ,此参数是该属性的描述信息
    class Foo:
    
        def get_bar(self):
            return 'wupeiqi'
    
        # *必须两个参数
        def set_bar(self, value): 
            return return 'set value' + value
    
        def del_bar(self):
            return 'wupeiqi'
    
        BAR = property(get_bar, set_bar, del_bar, 'description...')
    
    obj = Foo()
    
    obj.BAR              # 自动调用第一个参数中定义的方法:get_bar
    obj.BAR = "alex"     # 自动调用第二个参数中定义的方法:set_bar方法,并将“alex”当作参数传入
    del Foo.BAR          # 自动调用第三个参数中定义的方法:del_bar方法
    obj.BAE.__doc__      # 自动获取第四个参数中设置的值:description...

     

     

    类成员的装饰符

    对于一个类的成员而言有两种形式:

    • 公有成员,在任何地方都能访问
    • 私有成员,只有在类的内部才能使用,私有成员命名时,前两个字符是下划线。(特殊成员除外,例如:__init__ , __call__ , __dict__ 等)
    class C:
     
        def __init__(self):
            self.name = '公有字段'
            self.__foo = "私有字段"

     

    私有成员和公有成员的访问限制不同:

    变量:

    • 公有变量;类可以访问,类内部可以访问;派生类可恶意访问
    • 私有变量;仅类内部可以访问
    class C:
    
        name = "公有静态字段"
    
        def func(self):
            print C.name
    
    class D(C):
    
        def show(self):
            print C.name
    
    
    C.name         # 类访问
    
    obj = C()
    obj.func()     # 类内部可以访问
    
    obj_son = D()
    obj_son.show() # 派生类中可以访问
    
    #######################################
    
    class A:
    
        __name = "公有静态字段"
    
        def func(self):
            print C.__name
    
    class B(A):
    
        def show(self):
            print A.__name
    
    
    A.__name       # 类访问            ==> 错误
    
    obj = A()
    obj.func()     # 类内部可以访问     ==> 正确
    
    obj_son = B()
    obj_son.show() # 派生类中可以访问   ==> 错误

     

     

    类的特殊成员

    1,__doc__

    表示类的描述信息

    class Foo:
        """ 描述类信息,这是用于看片的神奇 """
    
        def func(self):
            pass
    
    print(Foo.__doc__)
    #输出:类的描述信息

    2,__module__ 和 __class__

    __module__  表示当前操作的对象在哪个模块

    __class__  表示当前操作的对象的类是什么

    #文件 lib/aa.py
    
    #!/usr/bin/env python3
    
    class C:
    
        def __init__(self):
            self.name = 'wupeiqi'
    #######################
    
    from lib.aa import C
    
    obj = C()
    print obj.__module__  # 输出 lib.aa,即:输出模块
    print obj.__class__      # 输出 lib.aa.C,即:输出类

    3,__init__

    构造方法,通过类创建对象时,自动触发执行

    class Foo:
    
        def __init__(self, name):
            self.name = name
            self.age = 18
    
    
    obj = Foo('binges') # 自动执行类中的 __init__ 方法

    4,__del__

    析构方法,当对象在内存中被释放时,自动触发执行

    在python中一般无需定义,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

    5,__call__

    对象后面加括号,触发执行

    注:构造方法的执行是由创建对象触发的,即 :对象 = 类名() ;而对于__call__ 方法的执行是由对象后加括号触发的即 对象()或者类()()

    class Foo:
    
        def __init__(self):
            pass
        
        def __call__(self, *args, **kwargs):
    
            print('__call__')
    
    
    obj = Foo() # 执行 __init__
    obj()       # 执行 __call__

    6,__dict__

    类或对象中的所有成员

    class Province:
    
        country = 'China'
    
        def __init__(self, name, count):
            self.name = name
            self.count = count
    
        def func(self, *args, **kwargs):
            print( 'func')
    
    # 获取类的成员,即:静态字段、方法、
    print( Province.__dict__)
    # 输出:{'country': 'China', '__module__': '__main__', 'func': <function func at 0x10be30f50>, '__init__': <function __init__ at 0x10be30ed8>, '__doc__': None}
    
    obj1 = Province('HeBei',10000)
    print (obj1.__dict__)
    # 获取 对象obj1 的成员
    # 输出:{'count': 10000, 'name': 'HeBei'}
    
    obj2 = Province('HeNan', 3888)
    print( obj2.__dict__)
    # 获取 对象obj1 的成员
    # 输出:{'count': 3888, 'name': 'HeNan'}

    7,__str__

    如果一个类中定义了__str__方法,那么在打印对象时,默认输出该方法的返回值

    class Foo:
    
        def __str__(self):
            return 'binges'
    
    
    obj = Foo()
    print obj
    # 输出:binges

    8,__getitem__,__setitem__,__delitem__

    用于索引操作,如字典。以上分别表示获取,设置删除数据

    #!/usr/bin/env python3
    
     
    class Foo(object):
     
        def __getitem__(self, key):
            print( '__getitem__',key)
     
        def __setitem__(self, key, value):
            print('__setitem__',key,value)
     
        def __delitem__(self, key):
            print('__delitem__',key)
     
     
    obj = Foo()
     
    result = obj['k1']      # 自动触发执行 __getitem__
    obj['k2'] = 'wupeiqi'   # 自动触发执行 __setitem__
    del obj['k1']           # 自动触发执行 __delitem__

    9,__getslice__,__setslice__,__delslice__

    该三个方法用于分片操作,如:列表

    #!/usr/bin/env python3
    
     
    class Foo(object):
     
        def __getslice__(self, i, j):
            print( '__getslice__',i,j)
     
        def __setslice__(self, i, j, sequence):
            print ('__setslice__',i,j)
     
        def __delslice__(self, i, j):
            print ('__delslice__',i,j)
     
    obj = Foo()
     
    obj[-1:1]                   # 自动触发执行 __getslice__
    obj[0:1] = [11,22,33,44]    # 自动触发执行 __setslice__
    del obj[0:2]                # 自动触发执行 __delslice__

    10,__iter__

    用于迭代器,之所以列表,字典,元组可以进行for循环,是因为类型内部定义了__iter__

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    class Foo(object):
    
        def __init__(self, sq):
            self.sq = sq
    
        def __iter__(self):
            return iter(self.sq)
    
    obj = Foo([11,22,33,44])
    
    for i in obj:
        print i

    for循环语法内部

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    obj = iter([11,22,33,44])
    
    while True:
        val = obj.next()
        print val

     

     

     

    参考博客:http://www.cnblogs.com/wupeiqi/p/4766801.html

  • 相关阅读:
    开源 Serverless 里程碑:Knative 1.0 来了
    以一致的体验交付和管理云原生多集群应用
    iLogtail使用入门K8S环境日志采集到SLS
    如何在golang代码里面解析容器镜像
    mac vmware 无法复制粘贴
    使用vi编辑时上下左右方向键被转化为A、B、C、D
    left join 和 left outer join 的区别
    设计模式之 适配器模式
    设计模式之 命令模式
    设计模式学习之 策略模式
  • 原文地址:https://www.cnblogs.com/binges/p/5253815.html
Copyright © 2020-2023  润新知