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文件。


posted @ 2022-01-24 13:07  mmszxc  阅读(94)  评论(0)    收藏  举报