测试开发进阶(六)

测试开发进阶(六)

面向对象编程的三大特征:封装,集成,多态

封装:将数据和方法放在一个类中

继承:python中的一个类可以继承于一个或多个类,被继承的叫父类(基类,base class),继承的类叫子类

多态:一类事物拥有多种形态,一个抽象类有多个子类,(多态的概念依赖于继承),不同的子类对象调用相同的方法,产生不同的执行结果,多态可以增加代码的灵活性

多态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# -*- coding:utf-8 -*-
"""
@Describe: 0816
@Author: zhongxin
@Time: 2019-08-16 20:31
@Email: 490336534@qq.com
"""


class Animal(object):
"""动物类"""

def func(self):
print('动物类的func')


class Cat(Animal):
"""猫类"""

def func(self):
print('喵 喵 喵')


class Dog(Animal):
"""狗类"""

def func(self):
print('汪 汪 汪')


class Hero(object):
def func(self):
print('这是Hero类')


def func(ani_obj):
"""

:param ani_obj: 动物类的对象
:type: Animal object
:return:
"""
ani_obj.func()


if __name__ == '__main__':
a = Animal()
b = Dog()
c = Cat()
h = Hero()
print(isinstance(a, Animal)) # True
print(isinstance(b, Animal)) # True
print(isinstance(c, Animal)) # True
print(isinstance(h, Animal)) # False
func(a) # 动物类的func
func(b) # 汪 汪 汪
func(c) # 喵 喵 喵
func(h) # 这是Hero类

鸭子类型的体现:

  • 静态语言:上面传入的对象必须是Base类型或者它的子类,否则无法调用run()方法
  • 动态语言:传入的不一定是Base类型,也可以是其他类型,只要内部实现了run()方法

多态的意义:开放封闭原则

  • 对于一个变量,只需要知道它是Base类型,无需确切地知道它的子类型,就可以调用run()方法(调用方只管调用,不管细节)
  • 当需要新增功能,只需要新增一个Base的子类实现run(),就可以在原来的基础上进行扩展,这就是著名的开放封闭原则
  • 对扩展开放:允许新增Base子类
  • 对修改封闭:不需要修改依赖Base类的run()等函数

数据和自省

类里面的属性:类属性

  • 私有属性:以单下划线或者双下划线开头的属性
  • 公有属性:普通的属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class MyClass(object):
attr1 = 100 # 公有属性
_attr1 = 2000 # 私有属性
__attr2 = 3000 # 私有属性

print(MyClass.__dict__)
"""
{'__module__': '__main__',
'attr1': 100,
'_attr1': 2000,
'_MyClass__attr2': 3000,
'__dict__': <attribute '__dict__' of 'MyClass' objects>,
'__weakref__': <attribute '__weakref__' of 'MyClass' objects>,
'__doc__': None}
"""
print(MyClass.attr1) # 100
print(MyClass._attr1) # 2000
print(MyClass._MyClass__attr2) # 3000

使用私有属性优化单例模式 更安全

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class MyClass(object):
"""
MyClass文档注释
"""
attr1 = 100
_attr1 = 2000
__attr2 = 3000

def func(self, name):
"""
func方法
:param name:
:type str
:return:
"""
pass

print(MyClass.__doc__)
m = MyClass()
print(m.func.__doc__)

"""
MyClass文档注释


func方法
:param name:
:type str
:return:
"""

slots限制类拥有的属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Hero(object):
__slots__ = []
pass


h = Hero()
print(h.__slots__) # []
print(h.__dict__)
"""
Traceback (most recent call last):
File "/Users/zhongxin/Desktop/py/zx/06/0816_3.py", line 18, in <module>
print(h.__dict__) # {'name': 'zx', 'age': 18}
AttributeError: 'Hero' object has no attribute '__dict__'
"""
1
2
3
4
5
6
7
8
9
class Hero(object):
__slots__ = ['name']
pass


h = Hero()
h.name = 'zx'
print(h.name) # zx
print(h.__slots__) # ['name']

作用:不再生成__dict__节约内存

自定义属性访问

内置函数:

  • getattr() 获取对象属性
  • setattr() 给对象设置属性
  • delattr() 删除对象属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Hero(object):
def __init__(self, name):
self.name = name


h = Hero('zx')
print(h.name) # zx
setattr(h, 'age', 18)
print(h.age) # 18
print(getattr(h, 'name')) # zx
delattr(h,'name') # <=> del h.name
print(h.name)
"""
Traceback (most recent call last):
File "/Users/zhongxin/Desktop/py/zx/06/0816_4.py", line 23, in <module>
print(h.name)
AttributeError: 'Hero' object has no attribute 'name'
"""
  • __setattr__方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Hero(object):
def __init__(self, name):
print('-----init-----')
self.name = name

def __setattr__(self, key, value):
"""
给对象设置属性的时候会调用该方法
"""
print(self) # <__main__.Hero object at 0x1031c7550>
print(key) # name
print(value) # zx
print('-----setattr-----')
object.__setattr__(self, key, value)


h = Hero('zx')
"""
-----init-----
<__main__.Hero object at 0x1031c7550>
name
zx
-----setattr-----
"""
print(h.name) # zx
  • __delattr__方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Hero(object):
def __init__(self, name):
print('-----init-----')
self.name = name

def __delattr__(self, item):
print(f'这个是item:{item}') # 这个是item:name
object.__delattr__(self, item)


h = Hero('zx')
print(h.__dict__) # {'name': 'zx'}
delattr(h, 'name')
print(h.__dict__) # {}
  • __getattribute__方法:查找属性,直接调用该方法进行查找
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Hero(object):
def __init__(self, name):
print('-----init-----')
self.name = name

def __getattribute__(self, item):
print(f'这个是item:{item}') # 这个是item:name
return object.__getattribute__(self, item)


h = Hero('zx')
print(h.name) # zx
print(h.name1)
"""
Traceback (most recent call last):
File "/Users/zhongxin/Desktop/py/zx/06/0816_7.py", line 26, in <module>
print(h.name1) # zx
File "/Users/zhongxin/Desktop/py/zx/06/0816_7.py", line 18, in __getattribute__
return object.__getattribute__(self, item)
AttributeError: 'Hero' object has no attribute 'name1'
"""
  • __getattr__:如果属性不存在,getattribute报AttributeError错误,该方法会主动捕获异常
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Hero(object):
def __init__(self, name):
print('-----init-----')
self.name = name

def __getattribute__(self, item):
"""查找属性,直接调用该方法进行查找"""
print(f'这个是item:{item}') # 这个是item:name
return object.__getattribute__(self, item)

def __getattr__(self, item):
"""如果属性不存在,getattribute报AttributeError错误,该方法会主动捕获异常"""
print(f'这是__getattr__的item:{item}')
return 999


h = Hero('zx')
print(h.name1)
"""
-----init-----
这个是item:name1
这是__getattr__的item:name1
999
"""
 wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!
您的支持将鼓励我继续创作!