相对路径就是相对于当前目录的路径。
常见的相对路径标记包括:
假设你当前的目录结果如下:
project/
|-- data/
| |-- input.py
| |-- print.py
| |-- test.py
|-- main/
| |-- main.py
test.py
文件里想打开input.py
文件input_path = ".input.py"
main.py
文件里想打开input.py
文件input_path = "..\data\input.py"
绝对路径就是文件或者目录在文件系统中的完整路径,不依赖于当前工作目录
在windows系统中,绝对路径以盘符开始
abs_path = "C:\Users\Username\Documents\file.txt"
在Unix/Linux系统中,绝对路径以根目录(“/”)开始
abs_path = "/home/username/documents/file.txt"
Py
文件就是一个模块# 方式一: import module_name, ...
# 方式二: from module_file import module1, module2, ...
# 方式三: from module_file import *
# 方式四: from module_file import module1 as m1
# 可以使用__all__变量(一般是列表)限制导入的内容
# 在模块的最顶层
# _开头的名字不会被*导入
# model_file.py
__all__ = ["name", "func1"]
name = "tom"
age = "18"
def func1():
...
def func2():
...
from model_file import *
name # 可以使用
age # 不可以使用
func1() # 可以使用
func2() # 不可以使用
# 1. 产生一个新的名称空间(名字是被导入的模块名)
# 2. 执行被导入模块文件代码, 将产生名字存放在的新的名称空间中
# 3. 将模块名称空间的名字添加到当前执行文件所在的名称空间
因为程序还没有结束,第一次导入的模块已经在内存中,导入产生的名称空间也在内存中
所以在此被导入时,不会在运行模块文件的程序代码,而是从内存中直接绑定引用
# 通过导入的模块名,引用模块内的内容
import module1
module.name
module.func()
# 只能访问module模块,不能访问module_file内其他的名字
from module_file import module
循环导入问题指的是在一个模块加载/导入的过程中导入另外一个模块,而在另外一个模块中又返回来导入第一个模块中的名字,由于第一个模块尚未加载完毕,所以引用失败、抛出异常。
究其根源就是在python中,同一个模块只会在第一次导入时执行其内部代码,再次导入该模块时,即便是该模块尚未完全加载完毕也不会去重复执行内部代码,只会在内存中找该模块,找不到就报错了。
示例
# m1.py文件
print("正在导入m1")
from m2 import y
x = "m1"
# m2.py文件
print("正在导入m2")
from m1 import x
y = "m2"
# run.py文件
import m1
# 执行结果
"""
正在导入m1
正在导入m2
报错
"""
# 分析
"""
import m1 # 导入模块m1
print("正在导入m1") # 打印"正在导入m1"
from m2 import y # 导入模块m2
print("正在导入m2") # 打印"正在导入m2"
from m1 import x # 导入模块m1 此时m1已经导入过了,不会重新导入,直接去m1拿x,拿不到就报错了
"""
# 执行结果
"""
正在导入m1
正在导入m2
正在导入m1
报错
"""
# 分析
"""
print("正在导入m1") # 打印"正在导入m1"
from m2 import y # 导入模块m2
print("正在导入m2") # 打印"正在导入m2"
from m1 import x # 导入模块m1
print("正在导入m1") # 打印"正在导入m1"
from m2 import y # 导入模块m2 此时m2已经导入过了,不会重新导入,直接去m2拿y,拿不到就报错了
"""
# m1.py文件
print("正在导入m1")
x = "m1"
from m2 import y
# m2.py文件
print("正在导入m2")
y = "m2"
from m1 import x
# run.py文件
import m1
print(m1.x)
print(m1.y)
# m1.py文件
print('正在导入m1')
def f1():
from m2 import y
print(x,y)
x = 'm1'
# m2.py文件
print('正在导入m2')
def f2():
from m1 import x
print(x,y)
y = 'm2'
# run.py文件
import m1
m1.f1()
# 先后顺序
# 先内存----然后内置----最后sys.path路径
import sys
sys.path # 是一个列表,存放各种文件夹的路径,当内存和内置不存在需要导入的模块时,会在sys.path中查找
sys.modules # 是一个字典,存放当前内存中已经存在的模块信息,键时模块名,值时模块绝对路径
# 1. 当脚本文件被执行
# 2. 当模块被导入文件
# 区别:
# 当脚本执行时,产生的名称空间在程序运行结束后失效回收
# 当模块时,导入运行的文件产生的名称空间在引用计数为0时被回收
# 每个py文件都有一个__name__属性
# 当py文件被当脚本执行时, __name__ == "__main__"
# 当py文件被当模块导入时, __name__ == "模块名"
__init__.py
的目录,该文件可以为空,也可以包含Python代码。这个文件告诉Python解释器该目录应被视为一个包,并且可以包含子模块或子包。__init__.py
文件,导入包就会执行__init__.py
文件,这也是__init__.py
文件存在的意义。my_package/
|-- __init__.py
|-- module1.py
|-- module2.py
|-- subpackage/
| |-- __init__.py
| |-- module3.py
| |-- module4.py
my_package
是一个包,因为它包含了 __init__.py
文件。module1.py
和 module2.py
是 my_package
的直接模块。subpackage
是一个子包,因为它包含了 __init__.py
文件。module3.py
和 module4.py
是 subpackage
的模块。import 包名.包名.模块名
from 包名.模块名 import 模块中的方法
__init__.py
文件__init__.py
为空时# 详细导入
from 包名.模块名 import 模块中的方法
__init__.py
为不为空时,有注册模块的方法或者变量名# 详细导入
from 包名 import 模块中的方法
# 1. 执行包的__init__.py文件
# 2. 产生一个名称空间,即__init__.py的名称空间,用于存放__init__.py文件执行过程中产生的名字
# 3. 在当前执行文件所在的名称空间中放一个包的名字,该名字指向__init__.py的名称空间
# import 包 :会将包的__init__.py文件执行一遍,得到的名字都是该__init__.py文件中存在的名字。
# 也就是说包里面的子包或者子模块如果不在__init__.py中,是不会被执行的,就不会导入
# 包结构文件
my_package/
|-- __init__.py
|-- module1.py
|-- subpackage/
| |-- __init__.py
| |-- module2.py
# module1.py
from my_package.subpackage import module2
print("Executing module1.py")
# module2.py
from my_package import module1
print("Executing module2.py")
.
来表示相对于当前模块所在的包的路径..
代表当前目录的上一级目录python - m mypackage.module1
# module1.py
from .subpackage import module2
print("Executing module1.py")
# module2.py
from .. import module1
print("Executing module2.py")
__all__
来控制使用者from包import*