入门 N day
-
有参装饰器
在给函数添加功能的时候,可以通过参数控制具体的操作(操作不固定)
''' 格式: def 函数名0(装饰器的形参列表): def 函数名1(func): def 函数名2(*agrs,**kwargs): result=func(*args,**kwargs) 添加的功能 return result return 函数名2 return 函数名1 有参装饰器的用法: @函数名0(装饰器实参列表) '''
写一个装饰器可以在函数结束后打印指定的任意提示信息
def end_message(x): def end(func): def new_func(*args,**kwargs): result = func(*args,**kwargs) print(x) return result return new_func return end @end_message('程序结束咯') def func1(x,y): print(x+y) func1(1,2)
练习:在原函数返回值的基础上减去指定的值
def end_(x): def end(func): def new_func(*args,**kwargs): result=func(*args,**kwargs) if type(result) in (int, float, bool, complex): return result-x return result return new_func return end @end_(15) def _(): return 10 print(_())
-
迭代器
迭代器是容器型数据类型(序列)
特点:
不能同时查看多个元素(直接打印看不到元素)
不能统计个数
不能查看长度
获取元素的时候只能一个一个取,每次取最上层的一个元素,取一个少一个
扫描二维码关注公众号,回复: 11995178 查看本文章—创建迭代器—
-
通过iter将其他序列转换成迭代器
-
创建生成器
iter1=iter([10,20,30,40]) print(iter1) # # <list_iterator object at 0x000000000069CF88> 看不到里面的元素 ''' print(len(iter1)) #TypeError: object of type 'list_iterator' has no len() 不能统计个数(查看长度) '''
从迭代器获取到元素,元素便不存在于迭代器里面了
每次只能取单个元素或者转换为其他序列 next(迭代器)和遍历
# 方法一 next iter1 = iter([10, 20, 30, 40]) print(next(iter1)) # 10 print(next(iter1)) # 20 next(iter1) # 取出来没有打印 print(next(iter1)) # 40 这是最后一个元素,此时迭代器为空 ''' print(next(iter1)) # StopIteration 对空的迭代器取元素,会报错 ''' # 方法二 遍历 iter2 = iter([10, 20, 30, 40]) for i in iter2: print(i) # 遍历iter2 依次将元素取出来直到迭代器为空 ''' iter3=iter('python!') list1=list(iter3) print(next(iter3)) # StopIteration 报错的原因是因为迭代器iter3转换成为了列表 那么原来iter3里面就没有元素了,所以再获取就会报错 ''' # 方法三 转换成列表 iters = iter((10, 20, 30, 40)) print(list(iters)) # [10, 20, 30, 40]
-
-
生成器
生成器的本质是一个迭代器,但是生成器数据来源和迭代器不同
如果迭代器看做是将鸡蛋(数据)一个叠一个放到容器里面的话
那么生成器就是放了一只母鸡(算法),需要多少个鸡蛋(鸡蛋)就提供多少
-
创建生成器
调用一个带有yield关键字的函数,就可以创建一个生成器对象
如果被调用的函数里面有yield,就不会执行函数体,也不会获取函数返回值
def func1(): print('+++++') print('====') yield return 100 result=func1() print(result)
-
怎么确定生成器中产生的数据
产生数据的个数:看执行生成器对应的函数会遇到几次yield
产生数据的值:看每次遇到的yield后面的数据是什么,没有数据就是None
def func2(): yield yield 'abc' for i in range(3): yield i gen1 = func2() print(gen1) list1 = list(gen1) print(list1, len(list1)) # [None, 'abc', 0, 1, 2] 5 def func3(x): yield yield 'abc' if x & 1: yield 100 return 20 yield 10 # 遇不到 print(list(func3(3))) # [None, 'abc', 100] 这里不会遇到20,因为前面有return函数体已经结束了
-
生成器产生数据的原理
调用函数创建生成器对象的时候不会执行函数体,获取生成器中的元素的时候才会执行,第一次获取元素会从函数体开始的位置开始执行,执行到第一次yield就停下来,并且将yield后的的数据作为这次获取的到的元素,后面每次获取元素的时候都是从上次结束的位置接着往后执行,执行到下一次yield又会停下来,如果从当前位置开始执行到函数结束没有遇到yield,是next获取就会报错
# 练习:写一个产生学号的生成器,能够产生指定学科001~999的学生学号 def subject(subject): def create_num(): for i in range(1, 1000): yield f'{subject}{i:0>3}' gen5 = create_num() for i in range(999): print(next(gen5)) subject('java') # 写一个能够产生所有正偶数的 def num(): x = 0 while True: x+=2 yield x nums=num() print(next(nums)) print(next(nums)) print(next(nums))
-
生成式 —生成器的推导式
将列表推导式的 [ ] 变为(),就是生成器的推导式—生成式
list1=[i**2 for i in range(10)] print(list1) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] # 生成式 gens=(i**2 for i in range(10)) print(next(gens)) # 0 print(next(gens)) # 1 print(next(gens)) # 4
- 模块
python中一个py文件就是一个模块,文件名就是模块名
可以在一个模块中去使用另外一个模块中的内容(没有在函数和类里面 的函数、类、变量)但是需要提前导入模块
假如存在一个模块,里面有如下代码:
print('.......')
A = 100
def func1():
print('test1中的函数')
for i in range(10):
pass
print('+++++++')
-
导入模块
在一个工程里面导入
import 模块名
导入后能够使用指定模块中的全局变量
以‘模块名.变量’的形式使用import test1 print(test1.A) #100 test1.func1() print(test1.i)
form 模块名 import 变量名1,变量名2…
导入模块,使用指定的全局变量
可以直接使用对应变量不需要以‘模块名.变量’的方式使用from test1 import A,func1 print(A) # 100 func1() #test1中的函数 print(i) # 会报错,因为没有导入i这个变量
-
模块重命名
import 模块名 as 新模块名
导入模块的时候对模块重新命名
重命名后需要使用新模块名来是用被导入的模块import test1 as new_test1 print(new_test1.A) # 100 new_test1.func1() # test1中的函数 print(new_test1.i) # 9
-
对指定变量进行重命名
form 模块名 import 变量名1 as 新变量名,变量名2,…
例from test1 import A as a,func1 print(a) # 100 func1() #test1中的函数
-
导入全部变量
from 模块名 import *
-
导入模块的原理
在导入模块的时候,系统会自动将被导入的模块中所有的代码都执行一遍
注意:
import 导入模块的时候自带查重功能
如果被导入的模块已经被导入了,不会重复导入from test1 import A as a,func1 # ....... ++++++++ '''
-
阻止导入 if name == ‘main’:
-
name 系统用来保存模块名字的变量
print(__name__) # __main__
每次运行当前py文件系统 name == main 会执行if后面的语句
如果导入模块,name != main 不会执行if后面的语句
因此会把不需要导入的部分放入if后面,就是阻止导入def func1(): pass def func2(): pass def main(): func1() func2() if __name__ == '__main__': main()
if语句外面放全局变量,里面进行函数调用
别人导入模块的时候就只会执行if外面的代码,而不会执行if里面的代码