一、模块
模块可以看成是一堆函数的集合体。
一个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内的文件代码为例。
1、import 模块名
语法如下:
import导入的模块,访问需要加前缀。
import首次导入模块发生了3件事:
以模块为准创造一个模块的名称空间
执行模块对应的文件,将执行过程中产生的名字都丢到模块的名称空间
在当前执行文件中拿到一个模块名
注意:模块的重复导入会直接引用之前创造好的结果,不会重复执行模块的文件。
导入重命名:smt变量指向span模块的名称空间
导入多个模块
2、from 模块名 import 具体的函数
语法如下:
这个声明不会把整个模块导入到当前的命名空间中,它只会将模块里的一个或多个函数引入进来。
from...import...导入的模块,访问不需要加前缀。
from...import...首次导入模块发生了3件事:
以模块为准创造一个模块的名称空间
执行模块对应的文件,将执行过程中产生的名字都丢到模块的名称空间
在当前执行文件的名称空间中拿到一个名字,该名字直接指向模块中的某一个名字,意味着可以不用加任何前缀而直接使用
优点:不用加前缀,代码更加精简
缺点:容易与当前执行文件中名称空间中的名字冲突
rom … import * 语句:导入文件内所有的功能:
3、循环导入
以下情况会出现循环导入:
可以使用函数定义阶段只识别语法的特性解决循环导入的问题,或从本质上解决循环导入的问题,但是最好的解决方法是不要出现循环导入。
方案一:
方案二:
4、dir() 函数
内置的函数 dir() 可以找到模块内定义的所有名称。以一个字符串列表的形式返回:
如果没有给定参数,那么 dir() 函数会罗列出当前定义的所有名称:
三、模块搜索路径
1、导入模块时查找模块的顺序
1、先从内存中已经导入的模块中寻找
如果我们在运行run.py文件的时候,快速删除mmm.py文件,我们会发现文件会继续运行,而不会报错,因为mmm已经被导入内存当中。如果我们再一次运行run.py时会报错,因为mmm.py已经被删除了。
2、内置的模块
验证先从内置中找,不会先找自定义的time.py文件。
3、环境变量sys.path中找(强调:sys.path的第一个值是当前执行文件的所在的文件夹)
如果mmm.py在C:\PycharmProjects\untitled\day16路径下,而执行文件路径为C:\PycharmProjects\untitled,如果普通导入一定会报错,我们可以把C:\PycharmProjects\untitled\day16添加到环境变量sys.path中,防止报错。
2、搜索路径以执行文件为准
假设我们有如下目录结构的文件,文件内代码分别是:
而hello和spam.py不是同目录下的,因此run.py的环境变量无法直接找到m2,需要从文件夹导入
四、Python文件的两种用途
一个模块被另一个程序第一次引入时,其主程序将运行。如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用name属性来使该程序块仅在该模块自身运行时执行。
python文件总共有两种用途,一种是执行文件;另一种是被当做模块导入。
每个模块都有一个name属性,当其值是'main'时,表明该模块自身在运行,否则是被引入。
1、当run.py运行的时候,aaa.py被当做引用模块,它的name == 'aaa'(模块名),会执行aaa.py中的f1()。
2、aaa.py被当做可执行文件时,加上name == 'main',单独运行aaa.py才会执行aaa.py中的f1()。 run.py运行时可以防止执行f1()。
五、包
包是一种管理 Python 模块命名空间的形式,包的本质就是一个含有.py的文件的文件夹。
包采用"点模块名称"。比如一个模块的名称是 A.B, 那么他表示一个包 A中的子模块 B 。
目录只有包含一个叫做 init.py 的文件才会被认作是一个包。
在导入一个包的时候,Python 会根据 sys.path 中的目录来寻找这个包中包含的子目录。
导入包发生的三件事:
创建一个包的名称空间
由于包是一个文件夹,无法执行包,因此执行包下的.py文件,将执行过程中产生的名字存放于包名称空间中(即包名称空间中存放的名字都是来自于.py)
在当前执行文件中拿到一个名字aaa,aaa是指向包的名称空间的
导入包就是在导入包下的.py,导入m1就是导入m1中的init。
1、两种方式导入:
import ... :
import item.subitem.subsubitem 这种导入形式,除了最后一项,都必须是包,而最后一项则可以是模块或者是包,但是不可以是类,函数或者变量的名字。
from ... import...:
当使用 from package import item 这种形式的时候,对应的 item 既可以是包里面的子模块(子包),或者包里面定义的其他名称,比如函数,类或者变量。
2、import 导入包内的模块
import 可以每次只导入一个包里面的特定模块,他必须使用全名去访问。
import方式不能导入函数、变量:import aaa.bbb.m3.f3错误
3、from import方式:
导入模块内具体的模块
这种方式不需要那些冗长的前缀进行访问
导入模块内具体的功能
这种方式不需要那些冗长的前缀进行访问
4、 绝对导入和相对导入
绝对导入:
相对导入:
.代表当前被导入文件所在的文件夹
..代表当前被导入文件所在的文件夹的上一级
...代表当前被导入文件所在的文件夹的上一级的上一级
5、from...import *
导入语句遵循如下规则:如果包定义文件 init.py 存在一个叫做 all 的列表变量,那么在使用 from package import * 的时候就把这个列表中的所有名字作为包内容导入。
这里有一个例子,在:file:sounds/effects/init.py中包含如下代码:
这表示当你使用from sound.effects import *这种用法时,你只会导入包里面这三个子模块。
六、软件开发的目录规范
为了提高程序的可读性与可维护性,我们应该为软件设计良好的目录结构,这与规范的编码风格同等重要,简而言之就是把软件代码分文件目录。假设你要写一个ATM软件,你可以按照下面的目录结构管理你的软件代码:
settings.py
common.py
src.py
run.py
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。