p81-
模块
- 什么是模块? py文件都是模块,模块不宜过大
- 包?文件夹就是包
模块的运行方式
-
脚本方式:用python解释器执行,cmd界面
-
模块方式:被其他的模块导入,为导入它的模块提供资源(变量,函数定义,类定义等)
-
自定义模块中可执行语句在被导入的时候 直接执行
-
python提供了一个工具可以判断自定义模块是开发阶段还是使用阶段_name_
print(__name__) #return __main__ 当前正在运行
print(__name__) #return 显示模块名
if __name__=='__main__':
for x in range(3): #return 被导入模块中可执行语句之前加if __name__=='__main__': 就不执行
print(x) #通常把可执行语句放到 函数中
系统导入模块路径
-
1、之前导入成功过模块,就在内存中找
-
2、内存中没有,在内置路径中,lib文件夹下,site-packages第三方包
-
3、sys.path 模块,集成到解释器了,是一个路径的列表[]
-
如果三个都找不到,就报错
-
PYTHONPATH: import的时候寻找模块的路径
-
一般都改第三个,如果模块在一些文件夹下,动态修改 sys.path
import os
os.path.dirname(__file__)#通常获取某个路径的父路径
标准模块写法
'''
自定义模块
'''
#这里是正式成员功能,函数,类等
#先写以下4行
def main():
pass
if __name__ == '__main__':
main()
模块的导入
- import xxx :导入模块所有成员
- import aaa,bbb :导入多个模块,不建议
- from xxx import a : 从xxx模块导入a成员,别的成员不用
- from xxx import a,b,c: 导入多个成员
- from xxx import *:导入模块所有成员
import xxx 和 from xxx import * 的区别
- 第一种方式在使用成员时,必须使用模块名作为前缀,time.time()
- 第二种方式在使用成员时,直接使用成员名,但是容易产生冲突
使用别名 alias解决冲突
from xxx import age as a
from xxx import * 方式下用_all_
_all_ 可以控制被导入模块中成员的使用,这个列表中有什么,就可以用什么,没有的不能用
相对导入
- 针对某个项目中的不同模块之间进行导入,称为相对导入
from ..dir import module #从与父目录同路径的dir 文件夹下导入module.py模块
随机数模块 random
#random
import random
print(random.random()) #取[0,1)的随机浮点数,可能取到0,不能取1
print(random.randint(1,100)) #取[1,100]的随机整数
print(random.uniform(2,10)) #取[2,10)的随机浮点数
lst = list(range(10)) #[0,1,2,3....9]
# random.shuffle(lst) #打乱顺序
# print(lst)
lst2 = random.sample(lst,5) #从x中随机抽取k个数据,返回列表
print(lst2)
函数总结
- 函数参数
- 1、实参
-
- 位置参数: 与形参一一对应
- 关键字参数:与形参一一对应
- 混合参数:位置参数在前,关键字参数在后
- 2、形参
- 位置参数:一一对应
- 默认参数:传值要覆盖,不传就是默认 def func(a,b,c=0)
- 万能参数:def func(*args,**kwargs)
- 仅限关键字参数:要放在*args 后面 def func(a,b,*args,c)
def func(a,b,*args,c):
print(a,b) #return 1 2
print(c) #return 555
func(1,2,3,4,c=555)
a,b=(1,2)
print(a,b) #return 1,2 拆包
a,b,*c=(1,2,3,4,5,6)
print(a,b,c) #return 1 2 [3, 4, 5, 6] ,c把最后的都接收了
- 空间
- 内置名称空间
- 全局名称空间
- 局部名称空间
- 作用域
- 全局作用域:全局名称空间,内置名称空间
- 局部作用域:局部名称空间,函数结束,内部开辟空间随之消失
- 取值顺序和加载顺序
- 先加载内置,然后全局,最后局部
- 取值顺序,就近原则,先局部,然后全局,最后内置
- 函数嵌套
- 遇到函数名+(),执行函数
- global
- 局部名称空间生命一个全局变量
- 局部修改全局变量
def func():
global name
name = 'tom'
print(name) #NameError: name 'name' is not defined 报错,应该放到func()下面
func()
name='jerry'
def func():
global name
name = 'tom'
print(name) #return jerry
func()
print(name) #return tom
-
nonlocal
- 不能操作全局变量
- 内层函数对外层的变量进行修改,用nonlocal
def func(): name = 'tom' def inner(): nonlocal name name='jerry' print(name) #return tom inner() print(name) #return jerry func()
-
函数名的应用
- 函数名是变量
- 函数名是函数体的地址
- 函数名可以做容器类型元素
- 函数名可以做函数参数
- 函数名可以作为函数返回值
-
迭代对象 ,迭代器,生成器,装饰器
-
迭代器:可以一直更新迭代的工具,内部含有__iter__的方法和__next__方法,可以用dir来看有没有这个方法
- 节省内存
- 惰性机制
- 不走回头路
-
缺点:
- 查询速度慢
- 不直观,操作方法少
-
可迭代对象:可以重复迭代的数据类型,内部含有iter
-
常见可迭代对象,str list dict tuple set range
-
可迭代对象:直观,操作方便,占内寸,可以转化成迭代器 iter(iterable)
-
生成器:
- 本质是迭代器,生成器 是自己用python构建的,三种方式
- 1、生成器函数
- 2、生成器表达式 跟列表推导式类似,[]换成()
- 3、函数中含有yield 就是生成器函数,函数名加括号得到生成器对象
- 生成器表达式和列表推导式对比
- 1、循环模式:(变量或者加工后的变量) for 变量 in iterable
- 2、筛选模式:(变量或者加工后的变量) for 变量 in iterable if条件
- 列表推导式 类似,只是用[]
-
装饰器,存在嵌套函数中,内层函数对外层函数非全局变量的引用, 闭包
-
闭包,对于引用的自由变量,不会在内存中消失,保证数据安全
-
自由变量 获取自由变量可以用 f._code_.co_freevars
-
装饰器本质是闭包
-
装饰器满足开放封闭原则
-
一般应用于登录认证,打印日志等,给函数在不改变原函数的代码及调用方式的前提下,给其增加额外功能。
-
装饰器基本结构,5行
-
-
内置函数,print pow len
#把list1 转 成 list2
list1 = [
{'name':'tom','hobby':'王者'},
{'name':'tom','hobby':'游泳'},
{'name':'tom','hobby':'电影'},
{'name':'jerry','hobby':'王者'},
{'name':'jerry','hobby':'音乐'},
{'name':'jerry','hobby':'吃'},
]
# list2=[
# {'name':'tom','hobby_list':['王者','游泳','电影',]},
# {'name':'jerry','hobby_list':['王者','音乐','吃',]}
# ]
list2 = []
for l1 in list1:
flag = False
for l2 in list2:
if l1['name'] == l2['name']:
flag=True
if flag==False:
dict1={}
dict1['name']=l1['name']
list3 = [l1['hobby']]
dict1['hobby_list']=list3
list2.append(dict1)
else :
for l3 in list2:
if l1['name'] == l3['name']:
l3['hobby_list'].append(l1['hobby'])
print(list2)