zoukankan      html  css  js  c++  java
  • python类和对象

    面向对象 Object Oriented Programing


    类的特性

    • 封装

    • 1、防止数据被随意修改

    • 2、使外部程序不需要灌注对象内部的构造,只需要通过此对象对外提供的接口进行直接访问即可

    • 继承

    • 1、类可以派生出子类

    • 2、父类里定义的属性、方法自动被子类继承

    • 3、通过父类=>子类的方式以最小代码量的方式实现 不同角色的共同点和不同点同时存在

    • 多态

    • 一个接口,多种实现;父类派生出不同的子类,子类在继承父类的相同方法同时又对父类的方法做了不同的实现,这也就是同一种事物表现出的多种形态。

    • 例:人类是一个父类,派生出中国人、美国人、西班牙人等子类,子类继承使用talk()方法,但不同人所说语言不同,talk()方法根据不同人表现出不同的交谈语言(中文、英文...)。

    • 即对不同对象发出的消息将会有不同的行为。例如:老板只要发出消息(工作),不同的员工对象将会按自己的职能进行不同的工作。


    类的定义

    class class_name(object):
        attr_name = value #类的公有属性,静态字段
        def __init(self,参数1,参数2...):#构造函数,初始化实例时执行
            self.name = 参数1
            ...#类的属性,成员属性,普通字段
    
        def func(self,参数1,参数2...):#类的方法
            pass
    
        def __del__(self):#析构函数,实例销毁时执行
            pass
    

    类的实例化

    var1 = class_name(参数1,参数2...)#这里传入构造函数中形参的实参
    

    类的私有属性

    self.__attrname用两个下划线开头定义为私有属性,只在类的内部可以访问

    只读访问私有属性

    • 在类中定义一个方法返回此属性,对外部提供只读访问接口
    def get_attrname(self)
        return self.__attrname
    
    • 强制访问(不要这么做)
      实例后跟‘.’,接一个下划线,接类名,接两个下划线的私有属性
    var1 = class_name()
    var1._class_name__attrname
    

    类的公有属性

    var1 = class_name(参数1,参数2)
    var2 = class_name(参数1,参数2)
    #上文定义类中,var1.name和var2.name是根据实例化时传入的参数1而不同,因此叫做成员属性
    #上文中在__init__前定义的attr_name则是公有属性,由每个实例共享
    
    #更改类的公有属性
    var1.attr_name = new_value#通过实例去修改,修改的是实例自己的公有属性
    #此时print(var1.attr_name)  值发生改变,print(var2.attr_name)  值未改变
    
    class_name.attr_name = new_value#通过类更改,修改的是所有以这个类实例化的对象的公有属性
    #此时print(var1.attr_name)  ,print(var2.attr_name)  值均已改变,且均为new_value
    

    面向对象编程(OOP)语言的一个主要功能就是【继承】

    • 继承是指使用现有类的所有功能,无需编写原来的类而进行这些功能的扩展
    • 通过继承创建的新类称为【子类】或【派生类】
    • 被继承的类称为【父类】、【基类】或【超类】
    • 继承可以通过【继承】(Inheritance)和【组合】(Composition)来实现
    • 在某些OOP语言中,一个子类可以继承多个基类。但一般情况下,一个子类只继承一个基类,要实现多重继承,可以通过多级继承来实现。

    继承的实现方式有两种

    • 实现继承
    • 使用基类的属性方法无需额外编码
    • 接口继承
    • 仅使用基类的属性和方法名称,但子类必须重构基类方法

    在考虑使用继承时,需要注意两个类之间应该是【属于】关系


    继承

    class class_name(object):
        def __init__(self,name,age):
            pass
       
        pass
    
    #子类
    class sun_class_name(class_name):
        def __init__(self,name,age,参数1...)#先继承,再重构,
            class_name.__init__(self,name,age)#继承父类构造方法
            #super(sun_class_name,self).__init__(name,age) #新式类写法
        pass
    
    • 子类构造函数如果重构,则先继承父类构造函数,再重构
    • 子类继承父类的属性和方法,如果重构方法,使用重构后方法

    新式类和经典类

    • 新式类和经典类在python3中都是广度查找来继承
    • 继承写法
    class_name.__init__(self,name,age)#继承父类构造方法
    #super(sun_class_name,self).__init__(name,age) #新式类写法
    

    封装

    • 类中封装了字段(属性)和方法
    • 对象(实例)中封装了:普通字段的值

    an example(组合封装)

    class F1(object):
        def __init__(self,n):
            self.N = n
            print("F1")
    
    class F2(object):
        def __init__(self,arg1):
            self.a =arg1
            print("F2")
    
    class F3(object):
        def __init__(self,arg2):
            self.b =arg3
            print("F3")
    
    #实例化
    o1 = F1("lmc")
    o2 = F2(o1)
    o3 = F3(o2)
    
    #s输出'lmc'
    o1.b.a.N
    

    继承

    class F1:
        def __init__(self):
            pring("F1")
        def a1(self):
            print("F1a1")
    
    class F2(F1):
        def __init__(self):
            pring("F2")
        def a1(self):
            print("F2a1")
    
    class F3(F2):
        def __init__(self):
            pring("F3")
        def a1(self):
            print("F3a1")
    
    #实例化
    obj = F3()
    #当执行obj.a1()时,因F3重构了a1()方法,此时调用F3.a1()
    obj.a1()->>"F3a1"
    

    class F1:
        def __init__(self):
            pring("F1")
        def a1(self):
            print("F1a1")
        def a2(self):
            print("F1a2")
    
    class F2(F1):
        def __init__(self):
            pring("F2")
        def a1(self):
            self.a2()
            print("F2a1")
        def a2(self):
            print("F2a2")
    
    class F3(F2):
        def __init__(self):
            pring("F3")
        def a2(self):
            print("F3a2")
    
    #实例化
    obj = F3()
    #当执行obj.a1()时,因F3未重构了a1()方法;F2重构了a1(),此时调用F2.a1(),
    #此时F2.a1()中第一句调用self.a2(),self即调用方法本身的对象F3,所以执行本身的F3.a2()
    #在父类里的self是当前调用方法对象,因obj->F3实例化后的指向是F3,所以为最底层的F3
    obj.a1()--->>"F3a2" [换行] "F2a1"
    

    静态方法

    • 字段

    • 普通字段/普通属性(保存在实例化的对象中)

    • 静态字段/静态方法(保存在类中)

    • 方法

    • 普通方法(保存在类中,实例化的对象进行调用,至少有一个self参数)

    • 静态方法(保存在类中,调用者-》类(无需创建对象),可以有任意参数):

    class F1:
        @staticmethod
        def a1(self):#静态方法self参数不是必须
            print("F1A1")
    
    F1.a1()直接调用,不必实例化。
    

    类的方法

    构造方法

    def __init__(self,arg1,arg2...)
        pass
    
    • 类实例化时直接调用,如有参数,实例化时需要同时传入参数

    析构方法

    def __del__(self):
        pass
    
    • 删除对象时(del class_name)或程序退出时调用

    获取类的属性字典

    查看类或对象中的所有成员

    • 类.__dict__,返回类的属性,以字典形式
    • self.__dict__

    @staticmethod静态方法

    • 相当于把这个标记下的方法断开和类的连接,和类没什么关系
    • 调用时直接class_name.func_name,可以不用实例化
    • 和类的唯一关联是调用时必须使用类名作为前缀,名义上归类管
    • self参数不需要

    @classmethod类方法

    • 类方法只能访问类变量,不能访问实例变量
    class A(object):
        name = 'alex'
        def __init_(self):
            self.name = 'wusir'
        
        @classmethod
        def test(self):
            print(self.name)
    
    a=A()
    a.test()
    结果:alex
    
    • 因此类方法一般用于禁止访问类的私有属性(实例化后的变量)
    • 当类的公有属性名和私有属性名一致时,类方法只能访问类的公有属性(类级变量)

    @property属性方法

    • 把一个类的方法变为一个静态属性
    class A(object):
        def __init__(self):
            self.name = 'alex'
    
        @property
        def eat(self):
            print('%s is eating...'%self.name)
    
    a = A()
    a.eat#不能加括号调用
    
    • 带参数的形式
    class A(object):
        def __init__(self):
            self.name = 'alex'
        
        @property
        def eat(self,food):
            print('%s is eating %s'%(self.name,food))
        
        @eat.setter
        def eat(self,food):
            print('set to food:',food)
            
    
    a = A()
    a.eat = 'baozi'
    
    • 可以将设置的参数用一个私有属性保存下来

    • 属性方法默认不能像一般属性一样删除,可以用删除存储的私有属性来做一个删除

        @eat.deleter
        def eat(self):
            del self.__food
    

    好吧,把一个方法变成静态属性有什么卵用呢?既然想要静态变量,那直接定义成一个静态变量不就得了么?well, 以后你会需到很多场景是不能简单通过 定义 静态属性来实现的, 比如 ,你想知道一个航班当前的状态,是到达了、延迟了、取消了、还是已经飞走了, 想知道这种状态你必须经历以下几步:

    1. 连接航空公司API查询

    2. 对查询结果进行解析

    3. 返回结果给你的用户

    因此这个status属性的值是一系列动作后才得到的结果,所以你每次调用时,其实它都要经过一系列的动作才返回你结果,但这些动作过程不需要用户关心, 用户只需要调用这个属性就可以,明白 了么?

    
    class Flight(object):
    
        def __init__(self,name):
    
            self.flight_name = name
    
    
    
    
    
        def checking_status(self):
    
            print("checking flight %s status " % self.flight_name)
    
            return  1
    
    
    
        @property
    
        def flight_status(self):
    
            status = self.checking_status()
    
            if status == 0 :
    
                print("flight got canceled...")
    
            elif status == 1 :
    
                print("flight is arrived...")
    
            elif status == 2:
    
                print("flight has departured already...")
    
            else:
    
                print("cannot confirm the flight status...,please check later")
    
    
    
    
    
    f = Flight("CA980")
    
    f.flight_status
    
    
    
    航班查询
    
    

    类的特殊成员方法

    __doc__ 表示类的描述信息

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

    __module__ __class__

    • __module__ 表示当前操作的对象在那个模块
    • __class__ 表示当前操作的对象的类是什么
    
    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,即:输出类
    

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

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

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

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

    __getitem____setitem____delitem__

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

    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'] = 'alex'   # 自动触发执行 __setitem__
    del obj['k1']  
    

    __new__详解:

    参考文档

  • 相关阅读:
    android状态栏
    python基础(二)——文件操作
    python基础(一)——字符串
    每日读书
    gradle相关
    EditText整体hint
    java生成pdf
    Androidstudio点9图报错
    【ASP.NET Core学习】使用JWT认证授权
    数据访问仓储模式的事务管理(Unit of Work)
  • 原文地址:https://www.cnblogs.com/limich/p/7477014.html
Copyright © 2011-2022 走看看