一、模块
1、基本概念
物理的角度:一个文件就是一个模块。
逻辑的角度:模块(功能划分)
模块中可以定义的内容: 类、函数、变量
模块的名字就是文件的名字,被存储在模块命名空间。
划分模块的好处:
(1)有利于项目按照功能进行划分,每个人负责一个模块,或者多个模块,方便协作开发。
(2)模块提供了独立的命名空间(全局命名空间),可以解决命名冲突问题。
(3)模块可以提供多人使用,提高程序的复用性。
在python中一个模块可以支持多个class的建立
2.模块的导入有两种方式
模块的导入方式分别为:import 和from …import两种方式
a)import方法
当我们导入一个模块之后,计算机会将该模块中所有的语句都编译执行,但是只在第一次import执行,只执行一次,再次导入也不会再执行了。
并且前模块中定义的变量或者函数不会跟导入模块中的变量或者函数名字冲突
可用如下方法进行验证:
新建一个名为for_test的python文件,内容如下:
x = "for_test模块中的x"
print(x)
在主程序文件中写入如下内容:
x = 1
print("主程序中的x:{}".format(x))
import for_test
print("主程序中的x:{}".format(x))
执行结果为:
主程序中的x:1
for_test模块中的x
主程序中的x:1
b)from…import方法
可以选择性导入模块中属性或者方法
from import 与import一样,在导入时,也会执行被导入模块下的所有代码
格式: from 模块名 import 属性、方法、类(如果有多个,也可以用,分隔)
使用from …import模式可能会造成跟当前模块中的名字冲突。谁在后面定义,以后面定义的名字为准。
访问:直接使用import进来的名字即可
新建一个名为for_test的python文件,内容如下:
x = "for_test模块中的x"
print(x)
def y():
print("for_test中的y")
在主程序中输入如下代码:
from for_test import x,y
x = 1
print("主程序中的x:{}".format(x))
y()
输出为:
for_test模块中的x
主程序中的x:1
for_test中的y
from 模块名 import * 将模块中所有名一次性全部导入(慎用,占内存空间)
dir()函数,返回指定对象相关绑定的名字,如果没有参数,会返回当前作用域下的名字
如下:
from for_test import x,y
print(dir())
输出:
for_test模块中的x
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'x', 'y']
3. 模块的别名
当导入模块的时候,可以是as为导入的模块名字进行重命名
使用语法如下:
import 模块名 as 模块别名
from 模块名 import 名称 as 名称别名, 名称 as 名称别名,…
需要注意的是: 一旦名字被重命名,原名字就不能再用了
import for_test as a
print(a.x)
a.y()
输出为:
for_test模块中的x
for_test模块中的x
for_test中的y
程序为:
from for_test import x as new_x,y as new_y
print(new_x)
new_y()
x=1
print(x)
输出为:
for_test模块中的x
for_test模块中的x
for_test中的y
1
别名的好处:
(1)可以解决当前模块和引用模块的命名冲突问题
(2)如果导入模块的名字很长,可以起到简化作用
4.隐藏模块的数据
需要注意的是:仅仅只对from import * 有用,对import不起作用
有两种方式:
a)标明不能被导入的名字
方法:名字前面_ 例如:_w
在for_test文件中写入:
from for_test import *
print(x)
y()
print(_w)
在主程序中写入:
from for_test import *
print(x)
y()
print(_w)
报错信息为:
NameError: name '_w' is not defined
如果直接写明from 模块 import 变量名 —不受不能导入的限制
如下:
from for_test import _w
print(_w)
输出:
for_test模块中的x
不被导入
b)标明能被导入的名字
方式: __all__
=[“能够被导入的名字”,“能够被导入的名字”…]
如果同时存在 __all__
和_x
类型时,先检索 __all__
中的变量,然后再去检索除了_x
以外的变量加入到 __all__
中
如下:
在for_test文件中写入如下:
x = "for_test模块中的x"
_w = "不被导入"
print(x)
z = "for_test中的z"
def y():
print("for_test中的y")
__all__= ["x","_w"]
在主程序中写入:
from for_test import *
print(x)
print(_w)
print(z)
输出为:
NameError: name 'z' is not defined
for_test模块中的x
for_test模块中的x
不被导入
5. __name__
的使用
能返回当前模块的名称
print(__name__)
输出:
__main__
一个模块一个py文件运行的时候,有两种方式:
一种方式是脚本执行(文件式),直接run --------__name__ ==__main__
另外一种方式是通过其他模块import当前模块-------__name__ ==模块的真实名字
具体使用方式如下:
在for_test中写入:
x = "for_test模块中的x"
_w = "不被导入"
z = "for_test中的z"
def y():
print("for_test中的y")
__all__= ["x","_w"]
if __name__ == "__main__":
print(x)
print(_w)
print(z)
y()
在主程序中写入:
import for_test
则没有输出。
可以将一些输出类的函数以及具体调用模块方法等写入if __name__ == "__main__":
条件下,那么当被调用时,则不会执行到这类语句
6.模块的搜索路径
搜索顺序
(1) 内建解释器
(2)作为脚本执行模块的所在路径
(3)python的环境变量路径
(4)python的安装路径(lib包下)
注意,模块起名字不要起lib包下的名字,也不要去用内建解释器下名字。
7. 模块的缓存
导入模块时,会产生一个缓存文件.pyc,字节码文件,预编译文件
产生的时间:模块导入的时候就产生了,自定义的py模块,在被导入的时候会创建
产生的位置:当前的文件路径下创建__pycache__包:
(1)缓存字节码文件只是提高模块的加载速度,并不是提高模块的运行速度
(2)只有自定义的模块才能产生字节码文件
(3)字节码文件可以脱离源文件执行(跨平台)
二、包
1. 基本概念
包提供了更加独立的命名空间,一个包可以包含多个模块,也可以包含多个子包
包的作用:
(1)提供模块的分类管理
(2)包提供了独立命名空间,解决模块重名的问题
2. 导入包
跟模块几乎是一样
import 包名
import 包名.模块名
from 包名 import 模块命名
from 包名.模块名 import 变量名、类名、函数名
3__init__.py文件
(1)__init__文件是每个python的开发包必须存在,否则python解释器会把当前的文件认为是普通目录,不会执行
(2)__init__可以是空的,也可以用来进行初始化,在__init__中定义的名称全部都是全局作用域的
(3)引用的时候,[包名].[名称]引用。名称被认为是包的属性
(4)在__init__下定义的变量,在整个包的所有py模块中都可以访问到。
(5)如果希望使用__init__中的变量,先要导入包
4.__all__变量
在__init__文件中可以使用过__all__控制使用,哪些是可以在使用【from 包名 import *】进行导入的,如同导入模块的使用一样