目录
1. 模块的四种形式
1.1 什么是模块
模块是一系列功能的集合体,而函数是某一个功能的集合体,因此模块可以看成是一堆函数的集合体。一个py文件内部就可以放一堆函数,因此一个py文件就可以看成一个模块。
import time
import requests
import os
1.2 模块的四种形式
-
自定义模块,common.py就叫做common模块
-
第三方模块,需要自己安装
-
内置模块:python解释器自带的,不需要安装
-
包 --》含有
__inti__.py
的文件夹,一种特殊的模块(解决了一个问题).把一系列模块组织到一起的文件夹
import time
print(time.time())
import datetime
print(datetime.datetime.now())
2. import 和 from...import
python看成一个手机,pip是应用管家,time就是应用管家里的一个应用,要用它,就要用 import导入
import time
time.time()
# import 发生的三件事:
# 1. 在内存中生存一个叫做time的名称空间
# 2. 运行time.py文件,然后把time.py文件内的名称空间放入time的名称空间内
# 3. 把time的名称空间指向import和from...import.py(当前导入time模块的文件)的名称空间中
# 使用import time导入的时候,使用方法只能time.方法名(),不能直接方法名
from time import gmtime,time
from time import * # 所有(等同于import time),不推荐使用,因为很容易造成变量
print(gmtime())
print(time())
# 1. 在内存中生成一个叫做time的名称空间
# 2. 运行time.py文件,让后把time.py文件内的名称空间放入time的名称空间内
# 3. 把gtime方法指向 import和from...import.py(当前导入time模块的文件) 的名称空间内
# __all__
from test import * # __all__限制了 from test import *
# from test import f3 # __all__不会限制
import test # __all__ 不会限制
f1()
f2()
test.f3()
import和from...import...的异同
相同点:
- 两者都会执行模块对应的文件,两者都会产生模块的名称空间
- 两者调用功能时,需要跑到定义时寻找作用域关系,与调用位置无关
不同点
- import需要加前缀;from...import...不需要加前缀
3. 循环导入
3.1 什么是循环导入
-
生成一个m2的名称空间
-
运行m2.py这个文件--> from m1 import x --> 生成一个m1的名称空间 --> 运行m1.py这个文件 --> from m2 import y
以上现象叫做循环导入问题
## m1.py
from m2 import y
x = 10
print('y:', y)
# m2.py
from m1 import x
y = 20
print('x:',x)
# 运行发生ImportError: cannot import name 'y'错误。
3.2 解决方案
我们可以使用函数定义阶段只识别语法的特性解决循环导入的问题,我们也可以从本质上解决循环导入的问题,但是最好的解决方法是不要出现循环导入。
方案一:
# m1.py
x = 10
def f2():
from m2 import y # ImportError: cannot import name 'y'
print(y)
f2()
# m2.py
y = 20
def f1():
from m1 import x
# ImportError: cannot import name 'x'
print(x)
f1()
# 运行m1, 找x ,直接打印了x --> 返回m1,继续打印y --> 返回m1打印x
方案二:
# m1.py
from m2 import y
x = 10
print('y:', y)
'''
y: 20
x: 10
y: 20
'''
# m2.py
y = 20
from m1 import x
print('x:',x)
# 运行m2.py找y --> y在上面,找到了y --> m2暂停运行 --> 继续运行m1.py,x =10 --> print('y:',20) --> m1运行完了,继续运行m2 --> 运行m1找x --> 找到了x,暂停运行m1 --> print('x:',10) --> m2结束了再去继续运行m1.py --> print('y:',20)
4. 模块的搜索路径
模块其实就是一个文件,如果要执行文件,首先就需要找到模块的路径(某个文件夹)。如果模块的文件路径和执行文件不在同一个文件目录下,我们就需要指定模块的路径。
模块的搜索路径指的就是在导入模块时需要检索的文件夹。
导入模块时查找模块的顺序是:
- 先从内存中找
- 内置的模块
- 自定制
- 环境变量sys.path中找
# 1. 先从内存中找
from m2 import y
print(y)
import time
time.sleep(10) # 10s内删除了m2
from m2 import y
print(y)
# 2. 内置
from time import time
print(time)
# 3.自定制
# 4. 环境变量中 (主要记住未来项目的执行文件一定要弄一个环境变量)
import sys
print(sys.path) # 环境变量,模块就是在这里找
sys.path.append(r'F:实习python 815')
# del sys.path[1]
print(sys.path)
import testt
testt.f1()
5. python文件的两种用途
python文件总共有两种用途,一种是执行文件;另一种是被当做模块导入。
编写好的一个python文件可以有两种用途:
- 脚本,一个文件就是整个程序,用来被执行
- 模块,文件中存放着一堆功能,用来被导入使用
# test.py
from m1 import x
print(x)
# m1.py
x = 10
# 执行文件: 当前运行的文件就叫做执行文件
# 模块文件: 运行test.py文件, m1就是模块文件
# 执行文件和模块文件是相对的
# m1.py
x = 10
print(__name__) # 当m1当做执行文件运行时, __name__ == '__main__'; 当m1被模块文件导入时 __name__ == m1
if __name__ == '__main__':
print(x) # 10
# m2.py
import m1
6. random模块
import random
# 最常用的方法
print(random.random()) # 0-1的随机数
print(random.randint(0,100)) # 0-100的整数
lt =[1,2,3,4,5,]
random.shuffle(lt) # 打乱lt的顺序
print(lt)
# 了解
print(random.randrange(1,10)) # 1,9之内的整数
print(random.uniform(1,3)) # 1-3的小数
print(random.choice([1,2,3,'a','b'])) # 选一个
print(random.sample([1,2,3,'a','b'],2)) # 选两个
def choice(lt):
ind = random.randint(0,len(lt)-1)
return lt[ind]
print(choice([1,2,3,'a','b']))