python 2.091 包、导入语法,循环调用,环境变量 py文件的变量name
第三方库的概念
什么是模块
模块的概念 : 模块就是一个功能的集合体,不是用来直接运行的,而是用来被导入使用的
三种来源
1内置模块:python解释器自带的
2第三方模块:需要去下载
3自定义的模式:自己写的
四种类别
1 一个py文件就是一个模块
2、文件夹也是一个模块,也就是包的概念
3、其他
为什么要用模块
第三方模块好处: 拿来主义,提升开发效率
自定义模块好处:别人的功能不够用,需要自己去编写 2、解决代码冗余
如何使用模块
导入模块发生的事情:
1、触发被导入的模块的运行,产生一个新的名称空间,把模块中的名字都丢进去
2、会在当前执行文件中得到一个名字spam,该名字指向被导入模块的名称空间
3、只在第一次导入的时候,会有名称空间和指向名称空间名字,之后的导入不会再执行模块的代码了
理解:
1、文件名是apam.py,模块名就是spam 就是导入的这个文件,
2、当使用import spam 这个模块的时候,就是运行了spam文件内的代码,
3、运行完代码后,产生了一个spam文件的名称空间,并且在运行文件内创建了一个名称空间的名字spam
4、在运行文件中,要spam文件内的变量或者函数时,要先问spam名字要,spam.xx
导入import , 加深理解名称空间的概念
'''
spam.py
money =200
def red1():
print('spam --- red1')
def red2():
global money
money=1
red1()
'''
import spam
money =100
def red1():
print('run -----red1')
def red2():
print(money)
red1() # 会打印哪一行
red2() # money 的值是多少
spam.red2() # 结果是什么
上述例子中,使用加深了名称空间的概念, 名称空间在代码定义的时候确定的,所以无论在哪个地方调用,还是要在自己的名称空间内去寻找
red1() # 会打印哪一行 run -----red1
spam.red2() # 结果是什么 spam --- red1
red2() # money 的值是多少 100
使用from + import 导入模块
from spam import red1,money
red1() # 只是指向了 spam的名称空间,但是并不改变的
print(money)
money=100 # 只是把指向了 spam的名称空间,断掉了,重新指向了一个新的内存地址 ,所以打印的值变化了
print(money)
上述的例子中 还是在判断 名称空间的概念
优点:导入的模块 每次都要加前缀, 简单的方式,不需要加导入模块的名字,但是 要想好 和 运行文件的名称空间是否有重合 (缺点)
把全部名称空间的名字全部引用进来 , 加剧了名称空间重合的冲突
from spam import *
red1()
red2()
print(money)
限制模块功能的调用
# 定义模块的时,只提供指定的功能供使用
# spam 模块只限制提供 red1 和 money 两个功能的调用
__all__=['red1','money']
from spam import *
red1()
red2() # 报错 没有这个函数
============================
__all__=['red1','money']
print('spam 模块')
money =200
def red1():
print('spam --- red1')
def red2():
global money
money=1
red1()
别名的另类使用+ 导入方式
不常用导入
import spam,m1,m2 可以在一行导入多个模块 ,不推荐
import aaaaaaaaaaaaaaaaaa as bb 如果一个模块的名字太长,可以使用as 设置别名
通过 as别名的设置还可以让 代码简洁
def sql():
pass
res = input('>>>>>>:')
if res == 'mysql':
import mysql as db:
elif res == 'mariadb':
import mariadb as db:
db.sql()
python 7.2 文件搜索的路径和
优先等级
当前执行文件去找的前提:
第一优先级 先从内存中区找已经导入的模块中去找
就是已经运行中的代码的模块
eg: 当一个程序一直运行时,删除程序模块的源文件,该程序再次调用模块时,不会停止或者报错
第二优先级 内置的模块
import sys
print(sys.modules) # 查看python 解释器加载到内存中的模块名称
# print(sys.__doc__)
import logging
print(logging) 打印一个模块文件的目录位置
第三优先级 前往sys.path 中的列表中,多个文件夹内依次检索去找模块
import sys
for i in sys.path:
print(i)
打印python的环境变量的路径
压缩包也是一个模块,也可以被导入使用
环境变量的添加
不同目录下的模块导入,添加环境变量
D:\py0000\venv\aaa\bbb\ccc.py 这个路径不在环境变量中,现在要加入到环境变量
import sys
sys.path.append(r'D:\py0000\venv\aaa\bbb')
# sys.path.append(r'D:\py0000\venv\aaa\bbb\') 添加的最后一个目录不要带\ 斜线了,会报错
for i in sys.path:
print(i)
import ccc
注意 sys.path.append 添加的模块的上一层的全局目录
当前程序所在的文件夹,是自动添加到环境变量中的。如果不是在同一个目录下的话,
就需要处理环境变量的问题,只要模块和执行程序不在同一个目录下,都要加环境变量的目录
同目录下导入ccc模块,启动文件start.py和aaa目录同级
from aaa.bbb import ccc 目录导入
其他方法,以下不推荐使用
import aaa.bbb.ccc 全部目录导入,调用麻烦
import aaa.bbb.ccc as c 设置别名也麻烦
循环调用 -- 屎上雕花
1、循环导入的问题
run.py
import m1
m1.py
print('正在导入 m1 模块')
from m2 import y
x = 'm1'
m2.py
print("正在导入 m2 模块")
from m1 import x
y = 'm2'
运行run.py,导入m1.py 时创建m1的名称空间,x='m1'这行代码还没有运行,所以m1的的名称空间中没有x 这个值,就跳到m2.py 中去了,
m2在运行中,导入m1 时,因为已经创建了m1的名称空间,所以m2中不会在创建了m1的名称空间,但是m2 要导入m1 的x的功能,因为没有,所以报错了。
# 解决1: 把import 导入的语句 放到代码的最下面,在创建完完整的名称空间后,在import 其他的模块,这样就不会报错了 -- 不推荐
run.py
import m1
m1.py
print('正在导入 m1 模块')
def f1():
from m2 import y
x = 'm1'
m2.py
print("正在导入 m2 模块")
def f2():
from m1 import x
y = 'm2'
解决2: 在解决循环导入的过程中 ,把具体一个功能需要使用循环导入时,把该功能导入的语句放到一个函数内,
利用函数不调用只扫描语法的性能,解决不运行代码的问题,避免了变量没有被赋值的情况。
使用这个功能的时候调用这个函数,就能找到函数的名称空间的值了
py文件的两种用途
yyy.py
def f1():
print('001')
print(__name__)
import yyy
def f1():
print('spam f1')
def f2():
print('spam f2')
在当前文件中导入yyy这个模块的时候,yyy的__name__ 的值就是模块的名字
print(__name__) #当文件被当作脚本直接执行时,__name__ 的值名为 "__main__"
print(__name__) #当文件被当作模块被导入时,__name__ 的值名为 "模块名"
if __name__ == '__main__': # 快捷键 type main tab键就可一
f1()
f2()
解读 : __name__ 这个变量是为了区分这个py文件的两种用途,
1、当文件被当作脚本直接执行时,__name__ 的值名为 "__main__"
2、当文件被当作模块被导入时,__name__ 的值名为 "模块名"
pyc文件的概念
> 在执行完login.py 在_pycache 目录下 发现pyc文件, pyc文件就是 预编译后的字节码文件
在python 执行程序过程:
当python 第一次执行一个程序hell.py 的时候,先编译源代码存到内存pycodeObject中,执行程序结束后,
会把pycodeObject 回写到文件中,这是pyc文件的由来。
当第二次执行这个程序的时候,编译器首先去目录中寻找,是否有这个程序的pyc文件,有的话,就直接加载执行,没有的话,就是编译。
如何判断一个程序源代码是否修改过那?
根据文件的时间戳,如果源代码文件的时间戳,大于pyc文件,就会直接编译程序, 执行完后,更新pyc。
如果源代码文件的时间戳,小于pyc文件,则执行pyc文件。
浙公网安备 33010602011771号