Python基础之模块详解

张开发
2026/4/18 7:36:23 15 分钟阅读

分享文章

Python基础之模块详解
一、模块模块可以看成是一堆函数的集合体。一个py文件内部就可以放一堆函数因此一个py文件就可以看成一个模块。如果这个py文件的文件名为module.py模块名则是module。1、模块的四种形式在Python中总共有以下四种形式的模块自定义模块如果你自己写一个py文件在文件内写入一堆函数则它被称为自定义模块即使用python编写的.py文件第三方模块已被编译为共享库或DLL的C或C扩展 如requests内置模块使用C编写并链接到python解释器的内置模块 如time包文件夹把一系列模块组织到一起的文件夹注文件夹下有一个__init__.py文件该文件夹称之为包2、为什么要用模块用第三方或者内置的模块是一种拿来主义可以极大地提升开发效率。自定义模块将我们自己程序中用到的公共功能写入一个python文件然后程序的各部分组件可以通过导入的方式来引用自定义模块的功能。二、如何用模块一般我们使用import和from...import...导入模块。以下述spam.py内的文件代码为例。1234567891011# spam.pyprint(from the spam.py)money1000defread1():print(spam模块, money)defread2():print(spam模块)read1()defchange():globalmoneymoney01、import 模块名语法如下1importmodule1[, module2[,... moduleN]import导入的模块访问需要加前缀。import首次导入模块发生了3件事以模块为准创造一个模块的名称空间执行模块对应的文件将执行过程中产生的名字都丢到模块的名称空间在当前执行文件中拿到一个模块名注意模块的重复导入会直接引用之前创造好的结果不会重复执行模块的文件。12345678# run.pyimportspam# from the spam.pyimportspammoney111111spam.read1()# spam模块1000spam.change()print(spam.money)# 0print(money)# 111111导入重命名smt变量指向span模块的名称空间12345678# run.pyimportspam as smmoney111111sm.moneysm.read1()# spam模块1000sm.read2sm.change()print(money)# 1000导入多个模块12345importspam, time, os# 推荐使用下述方式importspamimporttimeimportos2、from 模块名 import 具体的函数语法如下1frommodnameimportname1[, name2[, ... nameN]]这个声明不会把整个模块导入到当前的命名空间中它只会将模块里的一个或多个函数引入进来。from...import...导入的模块访问不需要加前缀。from...import...首次导入模块发生了3件事以模块为准创造一个模块的名称空间执行模块对应的文件将执行过程中产生的名字都丢到模块的名称空间在当前执行文件的名称空间中拿到一个名字该名字直接指向模块中的某一个名字意味着可以不用加任何前缀而直接使用优点不用加前缀代码更加精简缺点容易与当前执行文件中名称空间中的名字冲突12345# run.pyfromspamimportmoneyfromspamimportmoney,read1money10print(money)# 10rom … import * 语句导入文件内所有的功能12345678910# spam.py__all__[money,read1]# 只允许导入money和read1# run.pyfromspamimport*# 导入spam.py内的所有功能但会受限制于__all__money111111read1()# spam模块1000change()read1()# spam模块0print(money)# 1111113、循环导入以下情况会出现循环导入12345678# m1.pyprint(from m1.py)fromm2importxym1# m2.pyprint(from m2.py)fromm1importyxm2可以使用函数定义阶段只识别语法的特性解决循环导入的问题或从本质上解决循环导入的问题但是最好的解决方法是不要出现循环导入。方案一123456789101112131415# m1.pyprint(from m1.py)deffunc1():fromm2importxprint(x)ym1# m2.pyprint(from m2.py)deffunc1():fromm1importyprint(y)xm2方案二12345678910115、# m1.pyprint(from m1.py)ym1fromm2importx# m2.pyprint(from m2.py)xm2fromm1importy4、dir() 函数内置的函数 dir() 可以找到模块内定义的所有名称。以一个字符串列表的形式返回:123456789101112131415161718dir(sys)[__displayhook__,__doc__,__excepthook__,__loader__,__name__,__package__,__stderr__,__stdin__,__stdout__,_clear_type_cache,_current_frames,_debugmallocstats,_getframe,_home,_mercurial,_xoptions,abiflags,api_version,argv,base_exec_prefix,base_prefix,builtin_module_names,byteorder,call_tracing,callstats,copyright,displayhook,dont_write_bytecode,exc_info,excepthook,exec_prefix,executable,exit,flags,float_info,float_repr_style,getcheckinterval,getdefaultencoding,getdlopenflags,getfilesystemencoding,getobjects,getprofile,getrecursionlimit,getrefcount,getsizeof,getswitchinterval,gettotalrefcount,gettrace,hash_info,hexversion,implementation,int_info,intern,maxsize,maxunicode,meta_path,modules,path,path_hooks,path_importer_cache,platform,prefix,ps1,setcheckinterval,setdlopenflags,setprofile,setrecursionlimit,setswitchinterval,settrace,stderr,stdin,stdout,thread_info,version,version_info,warnoptions]如果没有给定参数那么 dir() 函数会罗列出当前定义的所有名称:123456789101112a[1,2,3,4,5]importfibofibfibo.fibprint(dir())# 得到一个当前模块中定义的属性列表# [__builtins__, __name__, a, fib, fibo, sys]b5# 建立一个新的变量 aprint(dir())# [__annotations__, __builtins__, __cached__, __doc__, __file__, __loader__, __name__, __package__, __spec__, a, b]delb# 删除变量名aprint(dir())# [__annotations__, __builtins__, __cached__, __doc__, __file__, __loader__, __name__, __package__, __spec__, a]三、模块搜索路径1、导入模块时查找模块的顺序1、先从内存中已经导入的模块中寻找如果我们在运行run.py文件的时候快速删除mmm.py文件我们会发现文件会继续运行而不会报错因为mmm已经被导入内存当中。如果我们再一次运行run.py时会报错因为mmm.py已经被删除了。1234567# test.pyimportm1# 从m1.py文件中导入的,然后会生成m1模块的名称空间importtime# 删除m1.py文件,m1模块的名称空间仍然存在time.sleep(10)importm1# 不报错,一定不是从文件中获取了m1模块,而是从内存中获取的2、内置的模块验证先从内置中找不会先找自定义的time.py文件。12345# time.pyprint(from time.py)# run.pyimporttimeprint(time)#3、环境变量sys.path中找强调sys.path的第一个值是当前执行文件的所在的文件夹123456789101112importsysforninsys.path:print(n)# C:\PycharmProjects\untitled\venv\Scripts\python.exe C:/PycharmProjects/untitled/hello.py# C:\PycharmProjects\untitled# C:\PycharmProjects\untitled# C:\Python\Python38\python38.zip# C:\Python\Python38\DLLs# C:\Python\Python38\lib# C:\Python\Python38# C:\PycharmProjects\untitled\venv# C:\PycharmProjects\untitled\venv\lib\site-packages如果mmm.py在C:\PycharmProjects\untitled\day16路径下而执行文件路径为C:\PycharmProjects\untitled如果普通导入一定会报错我们可以把C:\PycharmProjects\untitled\day16添加到环境变量sys.path中防止报错。123456# run.pyimportsyssys.path.append(rC:\PycharmProjects\untitled\day16)print(sys.path)importmmmmmm.f1()2、搜索路径以执行文件为准假设我们有如下目录结构的文件文件内代码分别是而hello和spam.py不是同目录下的因此run.py的环境变量无法直接找到m2,需要从文件夹导入12fromaaimportspamprint(spam.money)四、Python文件的两种用途一个模块被另一个程序第一次引入时其主程序将运行。如果我们想在模块被引入时模块中的某一程序块不执行我们可以用__name__属性来使该程序块仅在该模块自身运行时执行。python文件总共有两种用途一种是执行文件另一种是被当做模块导入。每个模块都有一个__name__属性当其值是__main__时表明该模块自身在运行否则是被引入。

更多文章