python - 模块
1. 模块的概念:最简单的一种就是以.py命名的文件
2. 模块的位置:
-
已编译好的(内置模块)
-
py文件(sys.path变量所提供的目录=环境变量中的目录)
-
当前目录
所以,必须将要导入的模块放置在当前目录,或sys.path所列出的目录内。搜索顺序:当前路径->sys.path目录
3. 导入模块的两种方式
-
import ...
-
from ... import ...
4. 导入系统模块
方法一:
time模块下有一个ctime()方法,用于获取当前时间
1 import time 2 3 print(time.ctime())
方法二:
如果确定只用到time下面的ctime()方法,也可以这样引用
1 from time import ctime 2 3 print(ctime()) # 现在使用时,就不必告诉Python,ctime()方法是time模块提供的了。若仍使用time.ctime(),则会报错NameError: name 'time' is not defined
方法三:
一次性把time模块下的所有方法都引入进来
1 from time import * 2 3 print(ctime()) 4 sleep(2) 5 print(ctime())
*星号可以把模块下的所有函数都导入进来,但并不推荐这样做。
如果导入的名称刚好和自己定义的函数重名,可以用as对导入的函数重命名,例如:
from time import sleep sleep(2)
from time import sleep as sys_sleep # 将sleep重命名为sys_sleep sys_sleep(2)
5. 导入自己编写的模块
例一:(同目录调用)
在practice.py中调用pub.py中的函数
pub.py
1 def add(a, b): 2 return a + b
practice.py
1 import pub 2 3 n = pub.add(1, 2) 4 5 print(n)
或
1 from pub import add 2 3 n = add(1, 2) 4 5 print(n)
ps:此时,你会发现在project目录下多了一个__pycache__目录,里面有一个文件pub.cpython-38.pyc。这是为了提高加载速度,每个模块会在__pycache__文件夹中存放该模块的预编译模块,命名为module.version.pyc
例二:(跨目录调用1)
如上图所示,practice.py和pub.py不在同一个目录(pub.py在module文件夹中)
practice.py
1 from module.pub import add 2 3 n = add(1, 2) 4 5 print(n)
例三:(跨目录调用2)
calculator.py
def add(a, b): return a + b
dd.py
from module import calculator m = calculator.add(4, 3) print(m)
例四:(跨目录、多层级文件调用1)- 将被导入模块的目录,加入到系统环境变量
count.py
1 class A(): 2 def add(self, a, b): 3 return a + b
new_count.py
1 from count import A 2 3 4 class B(A): 5 def sub(self, a, b): 6 return a - b 7 8 9 resulte = B().add(2, 5) 10 11 print(resulte)
practice.py
1 from module import new_count 2 3 n = new_count.B() 4 5 print(n.add(2, 5))
会报错:ModuleNotFoundError: No module named 'count'
报错分析:站在practice.py的位置,执行from count import A时,会在当前目录下找count名字的文件或目录,找不到
解决方案:将该目录加入到系统环境变量下即可,如下:
practice.py
将被导入模块所在目录,添加到系统环境变量path下即可
1 import sys 2 sys.path.append("./module") 3 4 from module import new_count 5 6 n = new_count.B() 7 8 n.add(2, 5)
例五:(跨目录、多层级文件调用2)- 将被导入模块的目录,加入到系统环境变量
count.py
class A(): def add(self, a, b): return a + b
new_count.py
from count import A class B(A): def sub(self, a, b): return a - b
dd.py
import sys from os.path import dirname, abspath project_path = dirname(dirname(abspath(__file__))) # 获取工程路径 sys.path.append(project_path + '\\module') # 拼接待导入文件的目录 from new_count import B # 导入该文件中的类 nn = B().add(4, 9) print(nn)
ps
print(__file__) # D:/zhangyang/PycharmProjects/test2/test/dd.py 文件所在路径 print(abspath(__file__)) # D:\zhangyang\PycharmProjects\test2\test\dd.py 文件绝对路径 print(dirname(abspath(__file__))) # D:\zhangyang\PycharmProjects\test2\test 上级目录 print(dirname(dirname(abspath(__file__)))) # D:\zhangyang\PycharmProjects\test2 上上级目录(工程目录)
6. 包
包含模块与一个特殊的__init__.py文件的文件夹,用于分层组织模块
ps:
在mac上不存在例4例5所示的问题,因为在new_count中导入count中的A类时,已经要求从顶层目录填写:
from count import A (不存在这种情况,因为会报错)
from module.count import A (这样写,不会有例4例5的问题)
所以,在mac上,正常导入即可(从工程顶层目录开始填写)