Python 测试
最编程
2024-10-06 19:10:16
...
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'])
上一篇: 马伊】社区工具包 社区工具包简介
下一篇: 一个简单的网络摄像头应用程序 6