zoukankan      html  css  js  c++  java
  • Python自动化开发学习的第七周---面向对象编程进阶

    一、面向对象高级语法部分

    1.多重继承  经典类vs新式类 

    class P1:
        def foo(self):
            print("P1-foo")
    
    class P2:
        def foo(self):
            print("P2-foo")
        def bar(self):
            print("P2-bar")
    
    class C1(P1,P2):
        pass
    class C2(P1,P2):
        def bar(self):
            print("C2-bar")
    
    class GC(C1,C2):
        pass
    

    经典类,通过在交互式的解释器中执行上面的声明,我们可以验证经典类使用的解释顺序,深度优先,从左至右。

    >>>gc = GC()
    >>>gc.foo()  #GC==>C1==>P1
    P1-foo >>>gc.bar() #GC==>C1==>P1==>P2
    P2-bar

    新式类 我们在类P1和P2的后面加上(object),就是新式类,重新执行下

    >>>gc = GC()
    >>>gc.foo()  #GC==>C1==>C2==>P1
    P1-foo
    >>>gc.bar() #GC==>C1==>C2
    C2-bar
    

    新式类,通过在交互式的解释器中执行上面的声明,我们可以验证经典类使用的解释顺序,广度优先,从左至右。

    2.静态方法、类方法、属性方法

    静态方法,通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法,什么是静态方法呢?其实不难理解,普通的方法,可以在实例化后直接调用,并且在方法里可以通过self.调用实例变量或类变量,但静态方法是不可以访问实例变量或类变量的,一个不能访问实例变量和类变量的方法,其实相当于跟类本身已经没什么关系了,它与类唯一的关联就是需要通过类名来调用这个方法

    class Dog(object):
    
        #name="zhangsan"
        def __init__(self,name):
            self.name=name
            self.__food__=None
    
        @staticmethod #静态方法,实际上脱离了类
        def eat(self):
            print("%s is eating %s"%("zhangsan","jiaozi"))
    
    
    d=Dog("ZhangSan")
    d.eat("baozi")
    
    运行结果:
    zhangsan is eating jiaozi
    

    类方法通过@classmethod装饰器实现,类方法和普通方法的区别是, 类方法只能访问类变量,不能访问实例变量

    class Dog(object):
    
        #name="zhangsan"
        def __init__(self,name):
            self.name=name
            self.__food__=None
    
    
        @classmethod  # 类方法,只能访问类变量,不能访问实例变量
        def eat(self,food):
            print("%s is eating %s" % (self.name, food))
    
    
    
    d=Dog("ZhangSan")
    d.eat("baozi")
    
    显示报错误:
    Traceback (most recent call last):
      File "E:/Ahappier/python/day10/静态方法.py", line 31, in <module>
        d.eat("baozi")
      File "E:/Ahappier/python/day10/静态方法.py", line 18, in eat
        print("%s is eating %s" % (self.name, food))
    AttributeError: type object 'Dog' has no attribute 'name'
    

    现在定义一个类变量叫name,看一下效果:

    class Dog(object):
    
        name="zhangsan"
        def __init__(self,name):
            self.name=name
            self.__food__=None
    
        @classmethod  # 类方法,只能访问类变量,不能访问实例变量
        def eat(self,food):
            print("%s is eating %s" % (self.name, food))
    
    
    d=Dog("ZhangSan")
    d.eat("baozi")
    
    运行结果:
    zhangsan is eating baozi
    

    属性方法的作用就是通过@property把一个方法变成一个静态属性

    class Dog(object):
        def __init__(self,name):
            self.name=name
            self.__food__=None
    
        @property  # 属性方法
        def eat(self):
            print("%s is eating %s" % (self.name, self.__food__))
    
    d=Dog("ZhangSan")
    d.eat("baozi")
    
    显示报错:
    ZhangSan is eating None
    Traceback (most recent call last):
      File "E:/Ahappier/python/day10/静态方法.py", line 29, in <module>
        d.eat("baozi")
    TypeError: 'NoneType' object is not callable
    
    把调用方法改变下:
    d=Dog("ZhangSan")
    d.eat
    
    显示:
    ZhangSan is eating None
    

    把一个方法变成静态属性有什么用处呢?既然要静态属性,那直接定义一个静态属性不就可以吗?以后你会很多场景不是简单的定义静态属性就可以的,比如,查看火车的当前状态,是到达了,走了,晚点了~~等等

    3.类的特殊成员方法

    3.1. __doc__  表示类的描述信息

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

    3.2. __module__ 和  __class__ 

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

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

    1 class C:
    2 
    3     def __init__(self):
    4         self.name = 'wupeiqi'
    lib/aa.py
    1 from lib.aa import C
    2 
    3 obj = C()
    4 print obj.__module__  # 输出 lib.aa,即:输出模块
    5 print obj.__class__      # 输出 lib.aa.C,即:输出类
    index.py= 

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

    3.4.__del__

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

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

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

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

    3.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'}
    

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

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

    3.8.__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']   
    

    3.9. __new__ __metaclass__

    http://www.cnblogs.com/alex3714/articles/5213184.html

    4.反射

     通过字符串映射或修改程序运行时的状态、属性、方法, 有以下4个方法

    class Foo(object):
     
        def __init__(self):
            self.name = 'wupeiqi'
     
        def func(self):
            return 'func'
     
    obj = Foo()
     
    # #### 检查是否含有成员 ####
    #hasattr(object,name)判断object中有没有一个name的字符串对应的方法和属性 hasattr(obj, 'name') hasattr(obj, 'func') # #### 获取成员 ####
    #getattr(object,name,default=None) getattr(obj, 'name') getattr(obj, 'func') # #### 设置成员 ####
    #setattr(x,y,v)==(x.y=v) setattr(obj, 'age', 18) setattr(obj, 'show', lambda num: num + 1) # #### 删除成员 ####
    #delattr(x,y)==del x.y delattr(obj, 'name') delattr(obj, 'func')

    5.动态模块导入

    lib = __import__("lib.aa")
    print(lib)
    obj = lib.aa.C().name
    print(obj)
    
    
    import importlib
    aa = importlib.import_module("lib.aa")
    print(aa)
    print(aa.C().name)
    View Code

     运行结果是:

    <module 'lib' from 'C:\python\day10\lib\__init__.py'>
    alex
    <module 'lib.aa' from 'C:\python\day10\lib\aa.py'>
    alex

     

    二、异常处理

    1.python中的错误异常

    你一定遇到过程序“崩溃” 或者因未解决的错误而终止的情况。你会看到“traceback/跟踪返回”的消息,以及随后解释器向你提供的信息,包括错误的名称,原因,以及发生错误的行号。不管你是通过python解释器执行还是标准的脚本执行,所有的错误都符合相似的格式,这提供了一个一致的错误接口。所有的错误,无论是语意上的还是逻辑上的,都是由于和python解释器的不相容导致的,其后引发的异常。

    2.检测和处理异常

    异常可以通过try语句来检测。任何在try语句块的代码都会被检测,检查有无异常发生

    try 语句有两种主要形式: try-except 和 try-finally . 这两个语句是互斥的, 也就是说你 只 能 使 用 其 中 的 一 种 . 一 个 try 语 句 可 以 对 应 一 个 或 多 个 except 子 句 , 但 只 能 对 应 一 个 finally 子句, 或是一个 try-except-finally 复合语句. 你可以使用 try-except 语句检测和处理异常. 你也可以添加一个可选的 else 子句处理没 有探测到异常的时执行的代码. 而 try-finally 只允许检测异常并做一些必要的清除工作(无论 发生错误与否), 没有任何异常处理设施. 正如你想像的,复合语句两者都可以做到. 

    核心笔记: 忽略代码, 继续执行, 和向上移交 try 语句块中异常发生点后的剩余语句永远不会到达(所以也永远不会执行). 一旦一个异常被 引发, 就必须决定控制流下一步到达的位置. 剩余代码将被忽略, 解释器将搜索处理器, 一旦找到, 就开始执行处理器中的代码. 如果没有找到合适的处理器, 那么异常就向上移交给调用者去处理, 这意味着堆栈框架立即回 到之前的那个. 如果在上层调用者也没找到对应处理器, 该异常会继续被向上移交, 直到找到合适 处理器. 如果到达最顶层仍然没有找到对应处理器, 那么就认为这个异常是未处理的, Python 解释 器会显示出跟踪返回消息, 然后退出.

    try:
        pass
    except Exception,ex:
        pass
    

    3.异常种类

     1 AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
     2 IOError 输入/输出异常;基本上是无法打开文件
     3 ImportError 无法引入模块或包;基本上是路径问题或名称错误
     4 IndentationError 语法错误(的子类) ;代码没有正确对齐
     5 IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
     6 KeyError 试图访问字典里不存在的键
     7 KeyboardInterrupt Ctrl+C被按下
     8 NameError 使用一个还未被赋予对象的变量
     9 SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
    10 TypeError 传入对象类型与要求的不符合
    11 UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
    12 导致你以为正在访问它
    13 ValueError 传入一个调用者不期望的值,即使值的类型是正确的
    14 
    15 常用异常
    常用异常
     1 ArithmeticError
     2 AssertionError
     3 AttributeError
     4 BaseException
     5 BufferError
     6 BytesWarning
     7 DeprecationWarning
     8 EnvironmentError
     9 EOFError
    10 Exception
    11 FloatingPointError
    12 FutureWarning
    13 GeneratorExit
    14 ImportError
    15 ImportWarning
    16 IndentationError
    17 IndexError
    18 IOError
    19 KeyboardInterrupt
    20 KeyError
    21 LookupError
    22 MemoryError
    23 NameError
    24 NotImplementedError
    25 OSError
    26 OverflowError
    27 PendingDeprecationWarning
    28 ReferenceError
    29 RuntimeError
    30 RuntimeWarning
    31 StandardError
    32 StopIteration
    33 SyntaxError
    34 SyntaxWarning
    35 SystemError
    36 SystemExit
    37 TabError
    38 TypeError
    39 UnboundLocalError
    40 UnicodeDecodeError
    41 UnicodeEncodeError
    42 UnicodeError
    43 UnicodeTranslateError
    44 UnicodeWarning
    45 UserWarning
    46 ValueError
    47 Warning
    48 ZeroDivisionError
    49 
    50 更多异常
    其他异常

    4.万能异常

    在python的异常中,有一个万能异常:Exception,他可以捕获任意异常,即:

    s1 = 'hello'
    try:
        int(s1)
    except Exception as e:
        print (e)
    

    接下来你可能要问了,既然有这个万能异常,其他异常是不是就可以忽略了!

    答:当然不是,对于特殊处理或提醒的异常需要先定义,最后定义Exception来确保程序正常运行。

    未完待续~~~

  • 相关阅读:
    Day1_Python基础
    选择排序(java版)
    冒泡排序(java版)
    手写数据库连接池(动态代理)
    JDBC增删查改(使用配置文件)
    JDBC demo
    JSP入门&会话技术
    response实现验证码图片
    android 定制自己的日志工具
    服务的最佳实践——后台执行的定时任务
  • 原文地址:https://www.cnblogs.com/garrett0220/p/6992026.html
Copyright © 2011-2022 走看看