美文网首页
python09-面向对象(二) & 异常

python09-面向对象(二) & 异常

作者: AndroidCat | 来源:发表于2017-05-11 16:15 被阅读0次

    面向对象

    • 回顾:

      • 反射:以字符串的形式去某个对象(模块,类,对象)操作它的成员(python中,一切皆对象)
      # 从模块中获取属性
      module = __import__('commons') # 引入commons模块
      if __name__ == '__main__':
          if hasattr(module, 'f1'):
              # print('ok')
              f1 = getattr(module, 'f1')
              ret = f1()
              print('ret =', ret)
      
      # 从类中获取属性
      class Cat:
          desc = 'YHH'
          def __init__(self, name):
              self.name = name
      
          def show(self):
              print(self.name)
      
      show = getattr(Cat, 'show')
      show(Cat('yhh'))
      
      # 从对象中获取属性
      cat = Cat('yhh')
      show = getattr(cat, 'show')
      show()
      
      • 多继承面试题:
      # 继承关系:
      # A(ooo) --> D
      # B(ooo) --> C(xxx,ooo) --> D
      class D(A,C):
          pass
      dog = D() # 创建D实例
      dog.xxx() # 调用xxx方法,只有C有,调用C的
      # 在xxx方法内部调用ooo方法,虽然C也有ooo方法
      # 但是函数内部调用方式为:self.ooo()
      # 根据继承的调用顺序,虽有调用的是A的ooo方法
      # 看别人的代码时,惊颤遇到这个问题--方法由谁发起的就由谁开始找
      
      • 继承中调用构造方法
        • 创建对象时会调用对象的__init__方法
        • 如果对象没有__init__方法,回去调用父类的构造方法
      class Animal:
          def __init__(self):
              print('Animal')
      class Cat(Animal):
          def __init__(self):
              print('Cat')
      cat = Cat() # Cat
      # =====================
      class Animal:
          def __init__(self):
              print('Animal')
      
      class Cat(Animal):
          # def __init__(self):
          #     print('Cat')
          pass
      
      cat = Cat() # Animal
      
      • 调用父类的构造方法
        • 调用父类的构造方法有两种方式:
      # 一:第一个参数为当前类,第二个参数为self
      # 表示找到Cat的父类并执行构造方法
      class Animal:
          def __init__(self):
              print('Animal')
      
      class Cat(Animal):
          def __init__(self):
              print('Cat')
              super(Cat, self).__init__()
      
      cat = Cat() # Cat Animal
      # 二:主动去调用父类的构造方法
      class Animal:
          def __init__(self):
              print('Animal')
      
      class Cat(Animal):
          def __init__(self):
              print('Cat')
              Animal.__init__(self)
      cat = Cat() # Cat Animal
      
    • 成员:

      • 反射:
        • 通过类-对象指针也能找到类中的方法
      class Cat():
          def __init__(self, name):
              self.name = name
          def show(self):
              print(self.name)
      
      cat = Cat('yhh')
      ret = hasattr(Cat, 'show') # 类中的方法
      print(ret) # True
      ret = hasattr(cat, 'name') # 对象的属性
      print(ret) # True
      ret = hasattr(cat, 'show') # 对象的方法
      print(ret) # True
      
      • 手动实现从导入模块到创建对象再获取对象属性的反射
      module = __import__('commons', fromlist=True)
      class_name = getattr(module, 'Cat')
      cat = class_name('yhh')
      name = getattr(cat, 'name')
      print(name) # yhh
      method = getattr(cat, 'show')
      method()
      
      • 静态字段:静态字段存在类中

        • 如果一个类中所有的对象都用共同的字段且想通过,可将此字段设置为静态字段
        • 在类中存在的字段为静态字段,在对象中存在的字段为普通字段
        class Province:
            country = 'China' # 静态字段
        
      • 类的成员:普通字段,普通方法,静态字段,静态方法,类方法,特性

        • 约定俗成:普通字段,普通方法由对象访问,静态字段,静态方法,类方法由类访问
        • 通过类访问普通方法需要参数需要传入对象
      • 静态方法

      class Cat:
          @staticmethod
          def show():
              pass
      
      • 类方法
        • 类方法其实相当于静态方法的另一种形式,只是调用时python自动将类名传给方法
      class Cat:
          @classmethod
          def show(cls):
              print(cls)
      
      Cat.show()
      
      • 特性(属性)

        • 执行方法一般为对象名.方法名()来调用,如果在定义方法的时候加上@property,那么调用该方法是不需要加上括号(前提是该方法不需要参数)
        • 当方法名和字段名相同,写在后面的会覆盖前面的,一般不会这么写
        • 作用:把方法伪造成字段来操作(比较鸡肋)
        class Cat:
            def __init__(self, name):
                self.name = name
            @property
            def show(self):
                print(self.name)
        
        cat = Cat('yhh')
        cat.show
        
        cat.name # 获取字段
        cat.name = 'newName' # 修改字段
        cat.show    # 通过特性,以字段的形式调用函数
        cat.show = 'haha'   # 报错
        # 如果想要不报错,则修改代码
        class Cat:
        def __init__(self, name):
            self.name = name
        @property
        def show(self):
            print(self.name)
        @show.setter
        def show(self,arg):
            self.name = arg
        
        cat = Cat('yhh')
        cat.show
        cat.show = 'catName'
        cat.show
        # 定义一个和@property方法名一样的方法,方法加上@方法名.setter就可以使得方法可以像修改属性一样传递参数
        
    • 修饰符:

      • 在方法或者字段前加上__表示私有
      • 私有的方法和属性不能被继承,只有自己能够访问
      • 私有也可以获取:
        • python中有个特殊的方法,私有的实行和方法也可以获取,一般不会这么用
      class Cat:
          __xo = 'xo'
          def __show(self):
              print('show')
          def pub(self):
              self.__show()
      cat = Cat()
      print(cat._Cat__xo)
      # 对象._类名__属性名或方法
      
    • 特殊方法:

      • __init__:构造方法,创建对象的时候调用
      • __del__:解析器销毁对象的时候调用
      • __call__:当调用对象名()的时候调用
        • Django,web框架的源码用到
      class Cat:
          def __init__(self):
              print('创建对象的时候调用')
          def __call__(self, *args, **kwargs):
              print('对象名()调用')
      
      cat = Cat() # 调用构造方法
      cat() # 调用call方法
      
      • __setitem__,__getitem__,__delitem__
        • 自定义section会用到
      • __str__
      li = list([11, 22, 33, 44]) # ls是一个对象
      print(li[1]) # 对象名[index]
      li[1] = 'index' # 对象名[index] = value
      del li[1] # del 对象名[index]
      print(li) # 打印对象
      print(str(li)) # str(对象名)
      
      # li是list类的一个对象,通过类似的,我们自己创建的一个对象
      
      class Cat:
          def __getitem__(self, item):
              print('getitem', item)
          def __setitem__(self, key, value):
              print('setitem', key, value)
          def __delitem__(self, key):
              print('delitem', key)
      
      cat = Cat()
      cat[1] # getitem 1
      cat['k1'] # getitem k1
      cat['key'] = 'value' # setitem key value
      del cat['key'] # delitem key
      
      # 通过切片时:
      cat = Cat()
      cat[1:2:3] # getitem slice(1, 2, 3)
      cat[1:2:3] = 123 # setitem slice(1, 2, 3) 123
      del cat[1:2:3] # delitem slice(1, 2, 3)
      
      # python2.7中操作切片时会调用:
      # __getslice__
      # __setslice__
      # __delslice__
      # 在python3.x中会调用:
      # __getitem__
      # __setitem__
      # __delitem__
      
      #==========================
      # 直接打印对象会调用对象的__str__()
      # 将对象转字符串也会调用__str__()
      class Cat:
          def __str__(self):
              return '调用str方法'
      
      cat = Cat()
      print(cat)
      print(str(cat))
      
      • dict:查看成员(比较重要)
        • 应用:自定义form框架的时候用
        • 获取对象里面所有的字段
      class Cat:
          def __init__(self, name):
              self.name = name
          def show(self):
              pass
          def fun(self):
              pass
      
      ret = Cat.__dict__
      print(ret)# {'__module__': '__main__', 'fun': <function Cat.fun at 0x102173ae8>, 'show': <function Cat.show at 0x102173a60>, '__weakref__': <attribute '__weakref__' of 'Cat' objects>, '__dict__': <attribute '__dict__' of 'Cat' objects>, '__init__': <function Cat.__init__ at 0x1021739d8>, '__doc__': None}
      obj = Cat('yhh')
      ret = obj.__dict__
      print(ret) # {'name': 'yhh'}
      
      • iter:
        • for循环对象时会调用__iter__方法
      li = list([11, 22, 33, 44, 55])
      for item in li:
          print(item)
      # li是list类的对象,for循环li对象时会遍历得到结果
      # 自定义对象遍历:
      class Cat:
          def __iter__(self):
              yield 11
              yield 22
              yield 33
              yield 44
      
      cat = Cat()
      for item in cat:
          print(item)
      
      • __new__ & __metaclass__

        • python中一切皆对象,类是对象,模块是对象,类创建的也是对象
        • 解析器解析到class关键字就会创建类对象(默认由type创建)
        class Cat:
            __metaclass__ = xxx # 表示由xxx来创建这个类
        # 创建类:
        Cat = type(Cat, (object,),{"fun1":func}
        # type(类名,(基类,..),{成员})
        

    异常

    • 编程难免遇到报错,如web网页尽量避免大黄页,应该让用户看到有好的错误页面.
    try:
        # 需要保护的代码
        li = [11, 2, 3]
        ret = li[5]
    except IndexError as IE:
        # 遇到异常时执行的代码块
        print(IE)
    except Exception as e:
        # 遇到异常时执行的代码块
        print(type(e))
    else:
        # 没有异常时执行的代码块
        print('no exception')
    finally:
        # 不管有没有异常都会执行的代码块
        print('finally')
    
    • 异常分类:
      • 所有异常都是Exception的派生类
    • 主动触发异常
    raise Exception('异常')
    
    try:
        raise Exception('发生异常')
    except Exception as e:
        pass
    
    • 断(意义不大)
    assert 1 == 1
    assert 2 == 1
    # 如果为真,则真
    # 如果为假,则抛异常
    # 做测试用,限制软件的运行环境等
    

    相关文章

      网友评论

          本文标题:python09-面向对象(二) & 异常

          本文链接:https://www.haomeiwen.com/subject/zygotxtx.html