Python 的测试

1.装饰器的使用 

# 1.装饰器的定义以及基本使用
def welcome(fn):
    def wrap(*args,**kargs):
        print('welcome')
        res = fn(*args,**kargs)
        return res
    return wrap
@welcome
def fn1(msg):
    print(f'fn1-{msg}')

@welcome
def fn2(msg):
    print(f'fn2-{msg}')

fn1('胖胖龙')
fn2('小小')

# 2.通过对装饰器函数进行嵌套,完成在装饰器上进行传参的需求
def welcome(outMessage):
    print(outMessage)
    def outwrap(fn):
        def wrap(*args,**kargs):
            print('welcome')
            res = fn(*args,**kargs)
            return res
        return wrap
    return outwrap
@welcome('是outmessage')
def fn1(msg):
    print(f'fn1-{msg}')

@welcome('out-message-2')
def fn2(msg):
    print(f'fn2-{msg}')

fn1('胖胖龙')
fn2('小小')

2.生成器

# 生成器基本使用
def compute(): # 这就是一个生成器
    for i in range(10):
        yield i ** 2

# 使用生成器
r = compute()
for cNum in r:
    print('cNum',cNum)

3.上下文管理器 

# 以开关文件对象举例  演示上下文管理器对象的使用

# 1.这是不用 上下文管理器的情况下,开关文件需要手动
# file = open('a.txt','w') # 用写的模式打开名为 a.txt的文件。这里没有该文件 就是在创建文件
# file.write('hello python') # 写入
# file.close()

# 2.上下文管理 处理文件开关 (这样就完成了,通过上下文管理器对象 + with 自动完成文件开关)  注:open('b.txt','w')返回的就是一个上下文管理对象
# with open('b.txt','w') as file:
#     file.write('hello python')  # 写入

# 3.自己实现一个 用于计算时间差的上下文管理器
import time
class Timer(): # 构造上下文管理器的类
    def __init__(self):
        self.timeGap = 0 # 初始化时间差值
    def __enter__(self): # 被包裹的代码块执行之前,要执行的函数
        self.startTime = time.perf_counter() # 记录开始的时候时钟的时间点
        return self # __enter__ 里面的返回值 就是 with 后面的那个 as 的值
    def __exit__(self, exc_type, exc_val, exc_tb): # 被包裹的代码块执行之后,要执行的函数
        self.endTime = time.perf_counter()  # 记录结束的时候时钟的时间点
        self.timeGap = self.endTime - self.startTime # 计算 时间差值

with Timer() as timer:
    arr = []
    for i in range(10000):
        arr.append(i ** 3)
print(timer.timeGap)

4.Type的使用

# 1.一个普通类的创建
# class student():
#     def __init__(self,name):
#         self.name = name
# xiaoming = student('xiaoming')
# print(xiaoming.name)

# 2.使用type类去动态的创建类

# 第一步,要创建用于动态创建 class_dict 的字符串。注:这个字符串里面就是在定义要创建的里面的类的内容。
# 扩展应用:既然这个 class_body 需要是一个字符串,那我们在实际使用中,可以将这个 class_body字符串放在一个文本文件里面,通过读取文件内容去动态生成类的内容。
# 这样做的好处就是我们可以通过修改文本文件的内容,在不修改代码的情况下 修改软件的功能!!!  十分牛逼
class_body = '''
def __init__(self,name):
    self.name = name
def study(self):
    print('studying')
def play(self):
    print('playing')
def showname(self):
    print(self.name)
'''
# 第二步,通过class_body字符串生成class_dict
class_dict = {}
exec(class_body,globals(),class_dict) # 用内置的函数生成类的内容并赋值给 class_dict字典
type_student = type('type_student',(object,),class_dict) # 使用 type类 动态生成新的类,其中 传给type函数的参数分别代表 类的名字,父类(必须是元组,用于多继承),类的内容字典
newstudent = type_student('maxiaotiao')
newstudent.study()
newstudent.play()
newstudent.showname()

5.MetaClass

# 1.先自定义一个 元类
class Human(type): # 继承 元类 type类
    @staticmethod
    def __new__(cls, *args, **kwargs): # 创建实例类时 自定义要做的事情
        print('args=',args)
        print('kwargs=', kwargs)
        class_ = super().__new__(cls,*args) # 先使用 type的初始化方法 将类实例创建起来
        # 自定义类的属性
        class_.freedom = True
        # 根据传入的参数 设置类实例的属性
        if kwargs:
            for key,val in kwargs.items():
                setattr(class_,key,val)
        return class_

# 2.使用刚刚创建的元类 创建一个类
class Student(object,metaclass=Human,country='china',sex='boy'): # 创建类的时候进行传参指定 该类的父类和元类
    pass

# 3.输出 student类上的属性
print(Student.freedom)
print(Student.country)
print(Student.sex)



6.metaclass

class Prop():
    def __init__(self,attrname):
        self.attr = f'_{attrname}'
    def get(self,instance): # getter方法,通过 property对象,可以把被propperty代理的类的当前正在被使用的实例 传过来(也就是这个 instance)
        if hasattr(instance,self.attr):
            return getattr(instance, self.attr)
        else:
            setattr(instance,self.attr,None)
            return None
    def set(self,instance,val): # setter方法
        setattr(instance,self.attr,val)

class Human(type):
    @staticmethod
    def __new__(cls, *args, **kwargs):
        class_ = super().__new__(cls,*args) # 常规的创建对应类
        propsNames = class_.props # 获取 类属性也就是 props = ['name','age'] 这个东西
        for propName in propsNames:
            pp = Prop(propName) # 为每一个属性 创建一个 Prop对象
            p = property(fset=pp.set,fget=pp.get) # 为每个属性创建property对象
            setattr(class_,propName,p) # 将property对象设置到类属性上(注:property对象只能设置在类属性上面)

        return class_


class Student(object,metaclass=Human):
    props = ['name','age']

student = Student()
print(student.name)
print(student.age)
student.name = 'kangkang'
print(student.name)

7.dataclass

import operator
from dataclasses import dataclass,field
# 1.dataclass基本使用
# @dataclass  # 使用 dataclass装饰器,让student类成为dataclass
# class student():
#     name:str
#     age: int
#
# s1 = student('kavi',17)
# s2 = student('ami',20)
# print(s1,s2) # 通过dataclass创建的实例,内部已经实现好了 __str__ 函数,会按照指定的格式打印
# print(s1==s2) # 内部把 __repr__ 方法也实现了 (比较对比的方法)。 只有在每个属性都相同的时候才会认为两个对象是相同的。

# 2.自定义属性的行为
# @dataclass(frozen=True,order=True)  # 使用 dataclass装饰器,让student类成为dataclass. frozen代表生成的对象是否可被修改,order表示对象实例是否支持排序(即在列表中存放这些对象的时候能否使用相关的sorted方法进行排序,默认是按照属性的顺序从前往后依次比较。通过调整属性顺序设置根据什么进行排序)
# class student():
#     name:str
#     age: int = 18 # 设置属性的缺省值,不传默认就是 18了
#     # 通过创建满足要求的field对象,来让 independent属性具备特定的行为。default代表默认值,init代表是否在init构造函数中体现该属性(false表示不出现在init函数中),repr表示打印时是否体现该属性,compare表示该属性是否参加对象的比较运算中
#     independent: bool = field(default=True,init=False,repr=True,compare=True)
#
#
# s1 = student('kavi')
# s2 = student('ami',20)
# ss = [s1,s2]
# print(s1,s2)
# print(s1==s2)
# print(sorted(ss))


# 3.更灵活的方式自定义属性的行为 + 第二种设置排序的方法
@dataclass()
class student():
    name:str
    age: int = 18 # 设置属性的缺省值,不传默认就是 18了
    independent: bool = field(default=True,init=False,repr=True)
    def __post_init__(self): # 这个函数会在实例初始化完成之后 执行。在这里可以做一些更加灵活的自定义属性的方法
        self.independent = self.age > 18 # 让属性的赋值加入一些逻辑行为

s1 = student('kavi')
s2 = student('ami',20)
ss = [s2,s1]
print(s1,s2)
print(s1==s2)
ss.sort(key=operator.attrgetter('age'))  # 通过往sort方法中传入key,指定排序规则来完成排序。
print(ss)


7.property类的使用

class student():
    def age_get(self):
        return self._age
    def age_set(self,age):
        if age < 0:
            raise Exception('age 数值错误')
        self._age = age
    age = property(fget=age_get, fset=age_set)  # 通过类属性的方式去使用 property类的实例

s = student()
s.age = 18
print(s.age)


8.mixin模式 

class dictMixin(): # 用于被其他类继承,让其他的类都能具有 将实例对象用类似字典的方法去进行操作(instance["key"])
    def __getitem__(self, key): # 当你用 instance[key]这样的类字典的形式去访问对象的某个属性时,就会触发这个函数
        return self.__dict__[key]  # __dict__ 属性记录了实例对象中的所有属性(数据类型为字典)
    def __setitem__(self, key, value): # 当通过类字典的方式去设置对象的属性的时候,就会触发这个函数
        self.__dict__[key] = value # 设置属性值

class student(dictMixin):
    def __init__(self,name,age):
        self.name = name
        self.age = age

s = student('kangkang',18)
print(s['name'])
print(s['age'])

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值