前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >测试开发进阶(六)

测试开发进阶(六)

作者头像
zx钟
发布2019-08-20 09:39:22
3630
发布2019-08-20 09:39:22
举报
文章被收录于专栏:测试游记

面向对象编程的三大特征:封装,集成,多态 封装:将数据和方法放在一个类中 继承:python中的一个类可以继承于一个或多个类,被继承的叫父类(基类,base class),继承的类叫子类 多态:一类事物拥有多种形态,一个抽象类有多个子类,(多态的概念依赖于继承),不同的子类对象调用相同的方法,产生不同的执行结果,多态可以增加代码的灵活性

多态

代码语言:javascript
复制
# -*- 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()等函数

数据和自省

类里面的属性:类属性

  • 私有属性:以单下划线或者双下划线开头的属性
  • 公有属性:普通的属性
代码语言:javascript
复制
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

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

代码语言:javascript
复制
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限制类拥有的属性

代码语言:javascript
复制
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__'
"""
代码语言:javascript
复制
class Hero(object):
    __slots__ = ['name']
    pass


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

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

自定义属性访问

内置函数:

  • getattr() 获取对象属性
  • setattr() 给对象设置属性
  • delattr() 删除对象属性
代码语言:javascript
复制
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方法
代码语言:javascript
复制
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方法
代码语言:javascript
复制
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方法:查找属性,直接调用该方法进行查找
代码语言:javascript
复制
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错误,该方法会主动捕获异常
代码语言:javascript
复制
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
"""
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-08-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 测试游记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 多态
  • 数据和自省
    • slots限制类拥有的属性
      • 自定义属性访问
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档