zoukankan      html  css  js  c++  java
  • Python------类的结构细分,异常处理,方法,属性

    1.类的私有成员

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

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

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

    静态字段(静态属性)

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

      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 C:
          __name = "私有静态字段"
          def func(self):
              print C.__name
      class D(C):
          def show(self):
              print C.__name
      C.__name       # 不可在外部访问
      obj = C()
      obj.__name  # 不可在外部访问
      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()  # 派生类中访问
        
      • 私有普通字段:仅类内部可以访问;

        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):
                  pass   
              def add(self):
                  print('in C')
          class D(C):
              def show(self):
                  print('in D')        
              def func(self):
                  self.show()
          obj = D()
          obj.show()  # 通过对象访问   
          obj.func()  # 类内部访问    
          obj.add()  # 派生类中访问  
          
        • 私有方法:仅类内部可以访问;

          class C:
              def __init__(self):
                  pass
              def __add(self):
                  print('in C')
          class D(C):
              def __show(self):
                  print('in D')
              def func(self):
                  self.__show()
          obj = D()
          obj.__show()  # 通过不能对象访问
          obj.func()  # 类内部可以访问
          obj.__add()  # 派生类中不能访问
          

      总结:

      对于这些私有成员来说,他们只能在类的内部使用,不能再类的外部以及派生类中使用.

      ps:非要访问私有成员的话,可以通过 对象._类__属性名,但是绝对不允许!!!

      为什么可以通过._类__私有成员名访问呢?因为类在创建时,如果遇到了私有成员(包括私有静态字段,私有普通字段,私有方法)它会将其保存在内存时自动在前面加上_类名.

    2.类方法与静态方法

    类方法:

    使用装饰器@classmethod。

    原则上,类方法是将类本身作为对象进行操作的方法。假设有个方法,且这个方法在逻辑上采用类本身作为对象来调用更合理,那么这个方法就可以定义为类方法。另外,如果需要继承,也可以定义为类方法。

    class Student:  
        __num = 0
        def __init__(self,name,age):
            self.name = name
            self.age= age
            Student.addNum()  # 写在__new__方法中比较合适,但是现在还没有学,暂且放到这里    
        @classmethod
        def addNum(cls):
            cls.__num += 1
        @classmethod
        def getNum(cls):
            return cls.__num
    a = Student('太白金星', 18)
    b = Student('武sir', 36)
    c = Student('alex', 73)
    print(Student.getNum())
    

    静态方法 :

    使用装饰器@staticmethod。

    静态方法是类中的函数,不需要实例。静态方法主要是用来存放逻辑性的代码,逻辑上属于类,但是和类本身没有关系,也就是说在静态方法中,不会涉及到类中的属性和方法的操作。可以理解为,静态方法是个独立的、单纯的函数,它仅仅托管于某个类的名称空间中,便于使用和维护。

    import time
    class TimeTest(object):
        def __init__(self, hour, minute, second):
            self.hour = hour
            self.minute = minute
            self.second = second
        @staticmethod
        def showTime():
            return time.strftime("%H:%M:%S", time.localtime())
    print(TimeTest.showTime())
    t = TimeTest(2, 10, 10)
    nowTime = t.showTime()
    print(nowTime)
    

    3.属性

    什么是特性property

    property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值.

    例一:BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解)
    成人的BMI数值:
    过轻:低于18.5
    正常:18.5-23.9
    过重:24-27
    肥胖:28-32
    非常肥胖, 高于32
      体质指数(BMI)=体重(kg)÷身高^2(m)
      EX:70kg÷(1.75×1.75)=22.86
      
    class People:
        def __init__(self,name,weight,height):
            self.name=name
            self.weight=weight
            self.height=height
        @property
        def bmi(self):
            return self.weight / (self.height**2)
    
    p1=People('egon',75,1.85)
    print(p1.bmi)
    

    为什么要用property

    将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则

    由于新式类中具有三种访问方式,我们可以根据他们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除

    class Foo:
        def __init__(self,name):
            self.name = name
        @property
        def aaa(self):
            print('111') # 获取,运行这
        @aaa.setter
        def aaa(self):
            print('222') # 修改,运行这
        @aaa.deleter
        def aaa(self):
            print('333') # 删除,修改这
    obj = Foo('alex')
    obj.name = 'dsb'
    obj.aaa = '太白'
    del obj.aaa
    print(obj.name)
    

    4.isinstance issubclass type.py

    class A:

    pass

    class B(A):

    pass

    class C(B):

    pass

    obj = B()

    print(isinstance(obj, B))

    print(isinstance(obj, A))

    print(isinstance(obj, C))

    对象与类之间的关系

    isinstance(obj,N): 判断 obj对象 是由N类(N的派生类)实例化的对象 返回 True.

    print(isinstance(obj, A))

    class A:

    pass

    class B(A):

    pass

    class C(B):

    pass

    类与类之间的关系

    issubclass(M,N) 判断是M类是N类的子孙.

    print(issubclass(C, B))

    print(issubclass(C, A))

    from collections import Iterable
    from collections import Iterator

    s1 = 'seewfsdkfl' # class str(Iterable) Iterable

    l1 = [1, 2, 3]

    print(type(s1)) # 判断的是对象从属于哪个类

    print(type(l1))

    print("iter" in dir(s1))

    print(isinstance(s1, Iterable))

    type 到底是什么?

    type 元类 python中一切皆对象 , 一个类也是一个对象.

    么这个(类)对象肯定是由类实例化出来的.

    python中你创建的所有类,以及大部分list str等等这些类,都是从type元类实例化得来的.

    python中继承object类都是新式类.

    object 也是由type元类实例化得来的.

    5.异常处理

    # 什么叫异常?
    # 你的程序出现中断,飘红,致使你的整个项目中断了.
    # 错误类型:
    # 语法错误.
    # 语法错误就不应该现在你的代码中.
    # 逻辑错误:
    
    1.用if进行异常处理
    # num = input('请输入:')
    # if num.isdecimal():
    #     num = int(num)
    #     if 0 < num < 6 :
    #         pass
    #     elif num == 10:
    #         pass
    # else:
    #     pass
    
    # 2.try单分支
    # try:
    #     l1 = [1,2,3]
    #     print(l1[100])
    #     dic = {1: 2,'a': 'b'}
    #     print(dic[3])
    #     num = input('请输入序号')
    #     int(num)
    # except IndexError as e:
    #     # print('处理了索引错误')
    #     print(e)
    # print(111)
    # print(222)
    
    try多分支
    # try:
    #     # l1 = [1,2,3]
    #     # print(l1[100])
    #     # dic = {1: 2,'a': 'b'}
    #     # print(dic[3])
    #     num = input('请输入序号')
    #     int(num)
    # except IndexError as e:
    #     print('处理了索引错误')
    # except KeyError as e:
    #     print('没有此键')
    # except ValueError as e:
    #     print('出现了转化错误')
    # print(111)
    # print(222)
    # 及时解决异常,避免程序中断.
    # 程序的分流.
    dic = {
        1: 111,
        2: 333,
        3: 555,
    }
    # while 1:
    #     try:
    #         num = input('请输入序号')
    #         int(num)
    #         print(dic[int(num)])
    
    #     except KeyError as e:
    #         print('选项超出范围,请重新输入')
    #     except ValueError as e:
    #         print('请输入数字')
    # print(111)
    # print(222)
    
    3.万能异常
    # try:
    #     num = input('请输入序号')
    #     int(num)
    #     print(dic[int(num)])
    # except Exception as e:
    #     print(e)
    # print(111)
    
    # 什么时候用万能异常,什么时候用多分支?
    #如果你只是想把这个异常处理掉,让程序继续执行. 万能异常.
    # 如果出现了异常,你是想根据不同的异常执行不同的逻辑流程,你要采取多分支.
    
    4.万能 + 多分支
    # dic = {
    #     1: 111,
    #     2: 333,
    #     3: 555,
    # }
    # while 1:
    #     try:
    #         num = input('请输入序号')
    #         int(num)
    #         print(dic[int(num)])
    
    #     except KeyError as e:
    #         print('选项超出范围,请重新输入')
    #     except ValueError as e:
    #         print('请输入数字')
    #     except Exception:
    #         pass
    5.异常处理其他成员
    # try:
    #     num = input('请输入序号')
    #     int(num)
    #     print(dic[int(num)])
    # except KeyError as e:
    #     print('选项超出范围,请重新输入')
    # except Exception:
    #     pass
    # # else:  # 如果上面无异常执行else语句,否则不执行else语句.
    # #     print(666)
    # finally: # 在整个程序终止之前,执行finally
    #     print('执行finally')
    
    # 1. 文件操作
    # try:
    #     f = open('register', mode='w')
    #     f.write('fdjsaklfd')
    #     f.write('fdjsaklfd')
    #     f.write('fdjsaklfd')
    #     l1 = [1, 2, 3]
    #     print(111)
    #     print(l1[1000])
    #     f.write('fdjsaklffjdsklaf')
    # finally:
    #     print('哈哈哈哈')
        # f.close()
    
    # 数据库: 连接数据库引擎.
    # try:
    #     int('e')
    # finally:
    #     print(777)
    
    # 在函数中 finally.
    # 结束函数之前,先要执行finally语句.
    
    # def func():
    #     try:
    #         a = 1
    #         b = 2
    #         return a + b
    #     finally:
    #         print(666)
    # func()
    
    6.主动抛出异常:
    # raise Exception('fdkslafjdslkf')
    
    7.断言:
    # assert 条件  # 源码上assert.
    # assert 1 == 2
    # print(11)
    # print(22)
    # print(33)
    
    
    8.自定义异常(了解)
    # TypeError
    # class Connection(BaseException):
    #     def __init__(self,msg):
    #         self.msg = msg
    # raise Connection('触发了连接异常')
    
    # 异常处理总结:
    # 异常处理不能经常使用:异常处理耗费性能.有些错误是需要进行分流使用.代码的可读性变差.
    # 关键节点使用.
    
    
    
  • 相关阅读:
    POJ 3114 Tarjan+Dijkstra
    278. First Bad Version
    209. Minimum Size Subarray Sum
    154. Find Minimum in Rotated Sorted Array II
    153. Find Minimum in Rotated Sorted Array
    710. Random Pick with Blacklist
    767. Reorganize String
    524. Longest Word in Dictionary through Deleting
    349. Intersection of Two Arrays
    350. Intersection of Two Arrays II
  • 原文地址:https://www.cnblogs.com/hql1117/p/11171800.html
Copyright © 2011-2022 走看看