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来确保程序正常运行。

未完待续~~~

posted @ 2017-06-12 11:28  Garrett0220  阅读(188)  评论(0编辑  收藏  举报
levels of contents