• 面向对象进阶篇


    上节补充

    当创建对象的类中没有我们想要执行的方法是,我们知道应该从它的父类里面找,如果父类里面有我们想找的方法,而且放下下面又包含方法时,包含的方法怎么执行呢?

    class A:
        def f1(self):
            print("A")
        def xxx(self):
            print("111")
    
    class B:
        def f1(self):
            self.xxx()
            print("B")
        def xxx(self):
            print("222")
    
    class C():
        def f2(self):
            print("C")
        def xxx(self):
            print("444")
    
    class D(C,B):
        def f(self):
            print("D")
    obj = D()
    obj.f1()
    

     

    我们知道对象可以执行自己的构造方法,那么我们既想对象执行自己的构造方法,又想执行父类的构造方法怎么办呢?

    1、super(当前类名,self).__init__()    推荐使用

    2、父类名.__init__(self)

    class annimal:
        def __init__(self):
            self.name = "动物"
            print("构造方法A")
    class cat(annimal):
        def __init__(self):
            self.tp = "喵"
            print("构造方法B")
            # super(cat,self).__init__()
            annimal.__init__(self)
    obj = cat()
    print(obj.__dict__)   #表示对象内所封装的成员
    
    构造方法B
    构造方法A
    {'name': '动物', 'tp': '喵'}
    

     派生类继承父类中init及方法中包含方法,找寻的思路(查找源码的过程

    如果派生类里面没有__init__构造方法,则去其父类中寻找(必须有继承关系)

    class annimal:
        def __init__(self):
            print("构造方法A")
    
        def f1(self):
            print("111")
    
    class cat(annimal):
        def __init__(self):
            self.f1()
            print("构造方法B")
            super(cat,self).__init__()
    
    obj = cat()            # cat()执行cat中__init__方法,__init__方法下又有self.f1 cat中没有f1方法去annimal中找
    111
    构造方法B
    构造方法A
    

    通过反射:通过类自能找类的成员

         通过对象既可以找对象里面的成员又可以找类里面的成员

    本章将重点讲解python类的成员,成员修饰符,类的特殊成员

    一、类的成员

    类的成员可以分为三大类:字段、方法、特性

     

    class qwe:
        age = 10                   #静态字段
        def __init__(self,name):  #构造方法
            self.name = name   # 普通字段
        def f1(self):          # 普通方法
            print("123")
        @staticmethod          #静态方法
        def f2(args,args1):
            print("zxx")
        @classmethod            #类方法
        def f3(cls):
            print(cls)
        @property               #特性(将方法伪造成字段)
        def f4(self):
            temp = self.name
            return temp
        @f4.setter
        def f4(self,value):
            print(value)
            self.name = value
    
    a = qwe("111")
    a.f1()
    qwe.f2(1,2)
    qwe.f3()
    print(a.f4)
    a.f4 = 456
    print(a.f4)
    

     注:所有成员中,只有普通字段的内容保存在对象中,既根据此类在对象中创建了多个对象,在内存中就有多少个普通字段,而其他的成员,则都保存在类中,既无论对象多少,内存中只有一份

    1、 类成员

    由上图可是:

    • 静态字段在内存中只保存一份
    • 普通字段在每个对象中都要保存一份

    字段分为:普通字段:   普通字段属于对象,普通字段用于对象有不同标签的情况

          静态字段:    静态字段属于类,将每个对象中存在的东西在类中保存一份(多个方法共同用到的参数)

    方法分为:普通方法:   def xxx(self)必须创建对象来访问方法

         静态方法:  通过在方法前加@staticmethod 而且方法中不用加self,而可以有其他参数       @staticmethod   不需要创建对象来访问方法

                                                       def xxx() 

         类方法:通过在方法前加@classmethod 而且方法中必须有cls(当前类的类名)                 @classmethod 

                                                             def xxx(cls)

    特性:通过在方法前加@property将方法伪造成一种字段(以字段的形式访问方法)参数只能是一个self         @property

       通过 对象.方法(方法后没有括号)obj.f1                             def xxx(self)

    下面的用于设置值

    @property               
    def f4(self):
        temp = self.name
        return temp
    @f4.setter
    def f4(self,value):
    
    class qwe:
        age = 10    #静态字段,存在类中
        def __init__(self,name):  #构造方法,存在了类中
            self.name = name   # 普通字段,存在对象中
        def f1(self):          # 普通方法,存在类中
            print("123")
        @staticmethod          #静态方法
        def f2(args,args1):
            print("zxx")
        @classmethod            #类方法
        def f3(cls):
            print(cls)
        @property               #特性(将方法伪造成字段)
        def f4(self):
            temp = self.name
            return temp
        @f4.setter
        def f4(self,value):
            print(value)
            self.name = value
    
    a = qwe("111")
    a.f1()
    qwe.f2(1,2)
    qwe.f3()
    print(a.f4)
    qwe.f4 = 456
    print(a.f4)
    

    规定:自己的成员自己去访问(除了类中的普通方法(本身也可以但是我们不这样做))

    通过类访问:   静态字段,静态方法、类方法(静态方法的特殊情况)

    通过对象访问:静态字段,类的普通方法、类的特性

    成员 :字段 :静态字段(每个对象都有一份),普通字段(每个对象都不同)

        方法 :静态方法(无需使用对象封装的内容),普通方法(使用对象封装的内容),类方法()

        特性 :普通特性(将一个方法伪造成字段的方式访问)

    快速判断调用:有self==>对象调用

           无self==>类调用

    2、类成员的修饰符

    类的所有成员在上一步骤中已经做了详细的介绍,对于每一个类的成员而言都有两种形式:

    • 公有成员,在任何地方都能访问
    • 私有成员,只有在类的内部才能方法

    私有成员和公有成员的定义不同:私有成员命名时,前两个字符是下划线。(特殊成员除外,例如:__init__、__call__、__dict__等)

    class C:
        def __init__(self):
    
            self.name = '公有字段'
    
            self.__foo = "私有字段"
    

    静态字段

      公有静态字段:类可以访问;类内部可以访问;派生类中可以访问

      私有静态字段:仅类内部可以访问;

    class C:
        
        def __init__(self):
            self.foo = "公有字段"
    
        def func(self):
            print self.foo  # 类内部访问
    
    class D(C):
        
        def show(self):
            print self.foo # 派生类中访问
    
    obj = C()
    
    obj.foo     # 通过对象访问
    obj.func()  # 类内部访问
    
    obj_son = D();
    obj_son.show()  # 派生类中访问
    
    class C:
        
        def __init__(self):
            self.__foo = "私有字段"
    
        def func(self):
            print self.__foo  # 类内部访问
    
    class D(C):
        
        def show(self):
            print self.__foo # 派生类中访问
    
    obj = C()
    
    obj.__foo     # 通过对象访问    ==> 错误
    obj.func()  # 类内部访问        ==> 正确
    
    obj_son = D();
    obj_son.show()  # 派生类中访问  ==> 错误
    

     1、对于自己私有的自由自己能访问,其派生类和父类都不能访问(意思就是在自己内部可以访问)
    成员修饰符:公有  任何地方都可以访问
       私有  只有在自己内部才可以访问,也可以在外部间接的访问私有的
    如果在外面非要访问私有字段的话也可以通过 对象_类名__字段(或方法)
    面向对象中一些常用特殊方法:__init__ 、__del__ 、

    class Foo:
    	__metaclass__ = MyType				#表示类由谁创建
    	def __init__(self):					#r = Foo()		实例化对象
    		print("xxx")
    	def __call__(self,*args,**kwargs):  #r()            执行此方法
    		print("xxx")
    		return 1
    	def __getitem__(self, item):		#r["xxx"]和r[x:x] 		执行此方法
    		print(item)
    	def __setitem__(self, key, value):	#r["xxx"] = 123 执行此方法
            print(key,value)	
    	def __delitem__(self, key):			#del r["xxx"]   执行此方法
            print(key)
    

     __dict__获取类或对象里面的成员,用法:xxx.__dict__ 
    __doc__获取注释

    r = Foo() #在类后面加括号执行__init__

    r() #在对象后面加括号执行__call__

    m = Foo()() #先Foo()实例化一个对象执行__init__,再在对象后面加括号执行__call__

    print(m) #获取对象加括号的返回值

    2、异常处理

    为了防止程序报一些未知的错误,不让用户看到大黄页(错误信息),而是可以把此转化到类外一个人性化的界面

    inp = input("请输入内容:")
    try:						#try里面就是捕获错误
        num = int(inp)
        print(num)
    except IndexError as e:		#IndexError 表示捕捉索引错误(特定的错误)
        print("索引错误")
    except Exception as e:		#这里的e表示封装了错误信息的对象,Exception表示所有类型错误的集合,是所有错误类的基类
        print(e)
    
     常用异常
     更多异常

    异常其他结构

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    try:
        # 主代码块
        pass
    except KeyError,e:
        # 异常时,执行该块
        pass
    else:
        # 主代码块执行完,执行该块
        pass
    finally:
        # 无论异常与否,最终执行该块
        pass

    主动触发异常

    1
    2
    3
    4
    5
    6
    7
    try:
        raise Exception('错误了。。。')
    except Exception,e:
        print e

    自定义异常

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    class WupeiqiException(Exception):
        def __init__(self, msg):
            self.message = msg
        def __str__(self):
            return self.message
    try:
        raise WupeiqiException('我的异常')
    except WupeiqiException,e:
        print e

    断言

    1
    2
    3
    4
    5
    # assert 条件
    assert 1 == 1
    assert 1 == 2
  • 相关阅读:
    使用Mutex实现程序单实例运行(c#)
    KMP(转载来自Matrix67原创)
    【转载】搞ACM的你伤不起(转载,不过这个神作实在是太经典了)
    POJ 3125 Printer Queue【打印队列】
    弱校ACM奋斗史
    POJ 2063 Investment
    程序员的艺术:排序算法舞蹈【视频】
    POJ 2063 Investment【经典完全背包】
    快速幂模板
    搞ACM的你伤不起(转载,不过这个神作实在是太经典了)
  • 原文地址:https://www.cnblogs.com/yezuhui/p/6853414.html
Copyright © 2020-2023  润新知