day12-迭代器生成器和模块
1.有参装饰器
- 有参装饰器
应用场景:如果实现装饰器的功能的时候需要额外的数据,就需要有参装饰器
def 函数名(参数列表):
定义无参装饰器函数
return 无参装饰器函数名
函数名 - 创建装饰器的函数名
参数列表 - 有多少个参数看实现装饰器的功能额外需要多少个数据
# def create_tag(name):
# def tag(f):
# def new_f(*args, **kwargs):
# result = f(*args, **kwargs)
# return f'<{name}>{result}</{name}>'
# return new_f
# return tag
# 写个装饰器将原函数的返回指加上指定的数
def create_tag(name):
def tag(f):
def new_f(*args, **kwargs):
result = f(*args, **kwargs)
if type(result) in (int, float, bool, complex):
result += name
return result
return new_f
return tag
@create_tag(100)
def func1(a, b):
return a + b
print(func1(100, 100))
2.迭代器
- 什么是迭代器(iter)
1)迭代器是容器型数据类型
2)迭代器无法直接获取所有的元素,只能一个一个的取(取指的是拿出来,只出不进);也无法通过len统计元素个数
3)创建迭代器的方法:a.将其他序列转换成迭代器 b.生成器
list1 = [1, 20, 39, 49]
i1 = iter(list1)
print(i1, type(i1))
# print(len(i1)) # 迭代器无法通过len统计个数
- 获取元素
不管以什么样的方式获取到了迭代器中的某个元素,那么这个元素在迭代器中就不存在了
- 获取单个元素
next(迭代器)
- 遍历
for 变量 in 迭代器
循环体
i2 = iter('hello')
print(next(i2))
print(next(i2))
print(next(i2))
3.生成器
- 什么是生成器(generator)
生成器 一种特殊的迭代器。
生成器 - 生产数据的机器,在存储的时候保存的是产生数据的算法而不是数据本身
语法:
调用带有yield关键字的函数就可以得到一个生成器
(如果一个函数中有yield,那么调用这个函数不会执行函数体,也不会获取返回值,函数调用表达式的值是一个生成器对象)
# 1.怎么创建生成器
def func1():
print('-----')
return 100
yield
result = func1()
print(f'result:{result}')
- 生成器产生数据的能力怎么确定
1)能创建多少个数据?有哪些?
a.执行完生成器对应的函数会遇到几次yield,那么这个生成器就可以创造多少个数据
b.每次遇到yield,yield后面的值是什么,对应创造的数据就是什么
def func2():
yield
- 生成器产生数据的原理
生成器对应的函数在调用函数的时候不会执行函数体;获取生成器中的数据的时候才会执行函数体
每次获取数据的时候都是从上一次结束的位置开始执行函数体,直到遇到yield就停下来,将yield后面的数据作为结果返回并记录结束位置
如果是next去取,执行的时候如果遇到函数结束都没有遇到yield就报错!
def func4():
yield 10
yield 100
yield 1000
yield 10000
yield 100000
gen3 = func4()
print('每一次', next(gen3))
for x in gen3:
print('x:', x)
# 练习:写一个生成器能够产生指定前缀指定长度的学号
# 前缀:py, 长度:4 py0001~py9999
def create_study_num(pre, length):
for x in range(1, 10**length):
result = pre + str(x).zfill(length)
yield result
nums = create_study_num('py', 3)
print(nums)
print(next(nums))
print(next(nums))
for _ in range(10):
print(next(nums))
4.模块
- 什么是模块
一个py文件就是一个模块
- 怎么在一个模块中使用另一个模块的内容
注意:如果一个模块想要被其他的模块使用,那么这个模块在命名的时候必须符合标识符的要求
一个模块想要使用另外一个模块中的内容必须先导入
‘’‘
1)import 模块名 - 能够使用模块中所有的全局变量;使用的时候通过 '模块名.'的方式
2)from 模块名 import 变量名1,变量名2,… - 能够使用模块中的指定变量;变量直接使用
3)模块重命名:import 模块 as 新模块名
4)变量重命名:from 模块名 import 变量 as 新变量名,变量,…
5)导入所有变量:from 模块名 import *
’‘’
1)第一种导入方式
# import silent
# print(silent.test_a)
# print(silent.x)
#
# silent.test_func()
2)第二种导入方式:from…import
# from silent import x, test_func
# print(x)
# test_func()
# print(test_a) # 没有导入的变量不能使用
# print(silent.test_a) # 报错
3)第三种导入方式:重命名
# import silent as TS
#
# test = 'hello'
# print(test)
#
# print(TS.test_a)
# from silent import x as silent_x, test_func
#
# for x in range(10):
# print(f'x:{x}')
#
# print(silent_x)
#
# test_func()
**4 )通配符 ***
from silent import *
print(x)
print(test_a)
5.导入模块的原理
- 原理
当代码执行到导入模块的时候,系统会自动将被导入的模块中的代码全部执行一遍
import silent(定义另外一个模块名为silent)
- 这个if语句中的代码在被别的模块导入的时候不会执行。if语句外面的会被执行,如果直接运行当前模块,模块这个if中的代码会被执行
if __name__ == '__main__':