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

测试开发进阶(五)

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

面向对象

魔术方法(魔法方法,特殊方法)

new方法和单例模式

__init__:在创建对象的时候,自动调用对 创建的对象 进行初始化设置的 魔术方法:以双下划线开头,双下划线结尾的方法

代码语言:javascript
复制
@staticmethod # known case of __new__
def __new__(cls, *more): # known special case of object.__new__
    """ Create and return a new object.  See help(type) for accurate signature. """
    pass

从源码可以看出,__new__方法的作用是创建然后返回一个对象

代码语言:javascript
复制
class Hero(object):
    def __init__(self, name):
        print('这个是init方法')
        self.name = name

    def __new__(cls, *args, **kwargs):
        # 创建对象时第一步做的就是__new__方法
        print('这个是new方法')
        return super().__new__(cls)


h1 = Hero('zx')
print(h1)
print(h1.name)
"""
这个是new方法
这个是init方法
<__main__.Hero object at 0x1033b1f60>
zx
"""
单例模式

类每次实例化的时候都会创建一个新的对象,如果要求类只能被实例化一次该怎么做?

普通模式:

代码语言:javascript
复制
class Hero(object):
    def __init__(self):
        print('这个是init方法')

h1 = Hero()
h2 = Hero()
print(id(h1), id(h2))  # 4328290400 4340056528

单例模式:

第一次创建对象存起来,之后创建对象的时候直接返回第一次创建的对象

实现思路:

  • 定义一个类属性,来记录该类是否创建过对象
  • new方法中
代码语言:javascript
复制
class MyClass(object):
    count = 0
    instance = None

    def __new__(cls, *args, **kwargs):
        if cls.count == 0:
            # 调用父类的__new__方法创建一个对象
            cls.instance = object.__new__(cls)
            cls.count += 1
        return cls.instance


h = MyClass()
h1 = MyClass()
h2 = MyClass()
h3 = MyClass()
print(id(h), id(h1), id(h2), id(h3)) # 4349229152 4349229152 4349229152 4349229152

# 精简
class MyClass(object):
    instance = None

    def __new__(cls, *args, **kwargs):
        if not cls.instance:
            # 调用父类的__new__方法创建一个对象
            cls.instance = object.__new__(cls)
        return cls.instance
上下文管理器

上下文管理器:上下文管理器是一个python对象,为操作提供额外的上下文信息。这种额外的信息,使用with语句初始化上下文,以及完成with块中的所有代码时,采用可调用的形式 with关键字:启动对象的上下文管理器

  • object.enter(self)

输入与次对象相关的运行时上下文。如果存在的话,with语句将绑定该方法的返回值到该语句的as子语句中指定的目标

  • object.exit(self, exc_type, exc_val, exc_tb)
代码语言:javascript
复制
with open('0814.py', 'r', encoding='utf8') as f:
    content = f.read()
    print(content)
代码语言:javascript
复制
class MyOpen(object):
    def __enter__(self):
        print('enter') # 1

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('exit') # 3

with MyOpen() as f:
    print(f) # 2

"""
enter 1
None  2
exit  3
"""
代码语言:javascript
复制
class MyOpen(object):
    def __enter__(self):
        print('enter') # 1
        return 999 # 2

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('exit') # 3

with MyOpen() as f:
    print(f) # 2

"""
enter 1
999   2
exit  3
"""

自己实现的文件操作上下文管理器

代码语言:javascript
复制
class MyOpen(object):
    def __init__(self, file_name, method, encoding):
        self.file_name = file_name
        self.method = method
        self.encoding = encoding
        self.f = open(self.file_name, self.method, encoding=self.encoding)

    def __enter__(self):
        return self.f

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.f.close()


with MyOpen('0814.py', 'r', encoding='utf8') as f:
    print(f.read())
代码语言:javascript
复制
exc_type # 异常类型
exc_val # 异常值
exc_tb # 异常回溯追踪
代码语言:javascript
复制
class MyOpen(object):
    def __init__(self, file_name, method, encoding):
        self.file_name = file_name
        self.method = method
        self.encoding = encoding
        self.f = open(self.file_name, self.method, encoding=self.encoding)

    def __enter__(self):
        return self.f

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.f.close()
        print(exc_type) # <class 'NameError'>
        time.sleep(0.5)
        print(exc_val) # name 'a' is not defined
        time.sleep(0.5)
        print(exc_tb)
"""
Traceback (most recent call last):
  File "/Users/zhongxin/Desktop/py/zx/05/0814_2.py", line 34, in <module>
    print(a)
NameError: name 'a' is not defined
"""


with MyOpen('0814.py', 'r', encoding='utf8') as f:
    print(a)

执行顺序:实例化(__init__)----> 执行__enter__---->执行with中的代码----->执行__exit__

str,repr方法
代码语言:javascript
复制
>>> a = 'abc'
>>> print(a)
abc
>>> a
'abc'

当我们使用print()这个内置函数之后,给他传入一个对象,实际上是触发了它的__str__方法,将方法返回的内容输出到控制台

代码语言:javascript
复制
class Hero(object):
    def __init__(self, name):
        self.name = name
h = Hero('zx')
print(h) # <__main__.Hero object at 0x103295908>


class Hero(object):
    def __init__(self, name):
        self.name = name

    def __str__(self):
        print('STR') # 1
        return '666' # 2


h = Hero('zx')
print(h)
"""
STR  1
666  2
"""

在交互环境中,输入对象,返回的是__repr__方法中所返回的内容

  • 内置函数str转化一个对象时候,触发str方法
  • 内置函数format处理对象时,触发str方法
  • 内置函数repr函数,触发repr方法
代码语言:javascript
复制
class Hero(object):
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return self.name


h = Hero('zx')
print(h) # zx
print(str(h)) # zx
print(repr(h)) # <__main__.Hero object at 0x1031c7860>

__repr____str__的备胎,当没有__str__的时候调用__repr__,反过来不会

算数运算相关的魔术方法
  • __add__:相加
  • sub:减法
  • mul:乘法
  • stuediv:除法
  • floordiv:整除
  • mod:取余
代码语言:javascript
复制
class MyStr():
    def __init__(self, value):
        self.value = value

    def __str__(self):
        return self.value

    def __add__(self, other):
        return f'{self}{other}'

    def __sub__(self, other):
        return f'{self}-{other}'


v1 = MyStr('aaa')
v2 = MyStr('bbb')
print(v1 + v2)  # aaabbb
print(v1 - v2)  # aaa-bbb

多个连续相加

代码语言:javascript
复制
class MyStr():
    def __init__(self, value):
        self.value = value

    def __str__(self):
        return self.value

    def __add__(self, other):
        return MyStr(f'{self}{other}')#⚠️


v1 = MyStr('aaa')
v2 = MyStr('bbb')
v3 = MyStr('ccc')
print(v1 + v2 + v3) # aaabbbccc

一个没啥用的减法实现

代码语言:javascript
复制
class MyStr():
    def __init__(self, value):
        self.value = value

    def __str__(self):
        return self.value

    def __add__(self, other):
        return MyStr(f'{self}{other}')

    def __sub__(self, other):
        return MyStr(self.value.replace(other.value, ''))


v1 = MyStr('aaa')
v2 = MyStr('bbb')
v12 = v1 + v2
print(v12)
print(v12 - v1)
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-08-14,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 面向对象
    • 魔术方法(魔法方法,特殊方法)
      • new方法和单例模式
      • 上下文管理器
      • str,repr方法
      • 算数运算相关的魔术方法
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档