1. 绝对路径引入
Python 在搜索模块时,依次搜索sys.path
里的位置,直到找到模块为止。下面命令可以查看当前的搜索路径:
import sys print(sys.path)
sys.path
的初始值来源于两个(其实还有一些更复杂但不常用的)。一个是系统的PYTHONPATH
变量,因此可通过设置该变量,来设置 Python 默认的搜索位置。比如:
export PYTHONPATH=/opt/python:$PYTHONPATH echo $PYTHONPATH
将该命令放在系统初始化脚本(/etc/environment)
或者 BASH 初始化脚本(/~/.bashrc)
里,可以对每个新开的窗口有效。
sys.path
的另一个来源是当前执行程序所在的目录 (而不是当前目录)。比如当前目录下文件夹./cc
下有一个b.py
,那么执行./cc/b.py
时,./cc
(而不是./!
)将被加到sys.path
:
python ./cc/b.py
2. 相对路径引用
上面说的是搜索模块都是指绝对路径引用。对于非系统目录,就需要操纵sys.path。但操纵sys.path有外溢效果,因为它是一个全局变量。对于同一个库里的模块的互相引用,可以考虑使用相对路径:
from . import abc from .abc import fool from ..up import foo
但相对路径有两个很恶心的问题,使得用法极为受限。其中一个是:
Note that both explicit and implicit relative imports are based on the name of the current module. Since the name of the main module is always __main__, modules intended for use as the main module of a Python application should always use absolute imports.
包含相对路径 import 的 python 脚本不能直接运行,只能作为 module 被引用。原因正如手册中描述的,所谓相对路径其实就是相对于当前 module 的路径,但如果直接执行脚本,这个 module 的 name 就是__main__, 而不是 module 原来的 name , 这样相对路径也就不是原来的相对路径了,导入就会失败。
在使用相对引用的文件中,不能有 __main__ 方法,只执行作为一个 module 进行引用,而不是直接执行脚本。
举个简单例子。假设./cc/
目录下已有一个./cc/b.py
(内容为空)。当前目录下的./a.py
内容为:
from .cc import b
那么直接运行python ./a.py
将会报错:
ModuleNotFoundError: No module named '__main__.cc'; '__main__' is not a package
另一个是常见的错误是: ValueError: attempted relative import beyond top-level package。
在涉及到相对导入时,package所对应的文件夹必须正确的被python解释器视作package,而不是普通文件夹。否则由于不被视作package,无法利用package之间的嵌套关系实现python中包的相对导入。
文件夹被python解释器视作package需要满足两个条件:
1、文件夹中必须有__init__.py文件,该文件可以为空,但必须存在该文件。
2、不能作为顶层模块来执行该文件夹中的py文件(即不能作为主函数的入口)。
补充:在"from YY import XX"这样的代码中,无论是XX还是YY,只要被python解释器视作package,就会首先调用该package的__init__.py文件。如果都是package,则调用顺序是YY,XX。
另外,练习中“from . import XXX”和“from .. import XXX”中的'.'和'..',可以等同于linux里的shell中'.'和'..'的作用,表示当前工作目录的package和上一级的package。
举个例子:
testIm/ --__init__.py --main.py : from Tom import tom --Tom/ --__init__.py : print("I'm Tom's __init__!") --tom.py : from . import tomBrother, from .. import kate,print("I'm Tom!") --tomBrother.py print(I'm Tom's Brother!) --Kate/ --__init__.py : print("I'm Kate's __init__!") --kate.py
运行文件:main.py
结果:
I'm Tom's __init__!
I'm Tom's Brother!
Traceback (most recent call last):
File "D:\PythonLearning\TestIm\main.py", line 3, in <module>
from Tom import tom
File "D:\PythonLearning\TestIm\Kate\kate.py", line 4, in <module>
from .. import kate
ValueError: attempted relative import beyond top-level package
>
可以看到from . import tomBrother顺利执行,首先执行了Tom文件夹下的__init__.py文件,后来执行了tomBrother.py文件,但是当执行到“from .. import kate”时报错,这是因为我们是在TestIm文件夹下把main.py文件作为主函数的入口执行的,因此尽管TestIm文件夹中有__init__.py文件,但是该文件夹不能被python解释器视作package,即Tom package不存在上层packge,自然会报错,相对导入时超出了最高层级的package。
修改方法:
test/ --main.py : from testIm.Tom import tom --testIm/ --__init__.py --Tom/ --__init__.py : print("I'm Tom's __init__!") --tom.py : from . import tomBrother, from .. import Kate,print("I'm Tom!") --tomBrother.py print(I'm Tom's Brother!) --Kate/ --__init__.py : print("I'm Kate's __init__!") --kate.py
运行文件:main.py
结果:
I'm top's __init__!
I'm Tom's __init__!
I'm Tom's Brother!!
I'm Kate's __init__!
I'm Tom!
即主函数入口不在TestIm中,则TestIm和其同样包含__init__.py文件的子文件夹都被python解释器视作package,形成相应的嵌套关系。可以正常使用from . import XXX和from .. import XXX。
以上就是详解Python中的路径问题的详细内容,更多关于Python 路径的资料请关注其它相关文章!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]