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

from Tom import tom

File "D:\PythonLearning\TestIm\Kate\kate.py", line 4, in

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 路径的资料请关注脚本之家其它相关文章!

python中filepath路径怎么写_详解Python中的路径问题相关推荐

  1. python中yaml模块的使用_详解Python yaml模块

    一.yaml文件介绍 yaml是一个专门用来写配置文件的语言. 1. yaml文件规则 区分大小写: 使用缩进表示层级关系: 使用空格键缩进,而非Tab键缩进 缩进的空格数目不固定,只需要相同层级的元 ...

  2. python中fp是什么意思_详解python实现FP-TREE进行关联规则挖掘(带有FP树显示功能)附源代码下载(3)...

    详解python实现FP-TREE进行关联规则挖掘(带有FP树显示功能)附源代码下载(3) 上一节简单讲了下FP树的生成,在这一节我将描述FP树的挖掘过程. 首先我们回顾一下要挖掘的特征项及样本空间: ...

  3. python中什么是可变参数_详解Python的三种可变参数

    详解Python的三种可变参数 可变参数 可变参数应该最简单,在C/C++和Java等语言中都有,就是用*号来表示,例如 def testArg(*arg) 你可以传入任意多个元素(包括0)到参数中, ...

  4. python中list[1啥意思_详解Python中list[::-1]的几种用法

    本文主要介绍了Python中list[::-1]的几种用法,分享给大家,具体如下: s = "abcde" list的[]中有三个参数,用冒号分割 list[param1:para ...

  5. python正则匹配空格+数字+空格_详解Python中正则匹配TAB及空格的小技巧

    详解Python中正则匹配TAB及空格的小技巧 发布时间:2020-10-15 08:38:48 来源:脚本之家 阅读:94 作者:杰瑞26 在正则中,使用.*可以匹配所有字符,其中.代表除\n外的任 ...

  6. python函数中可变参数的传递方式_详解Python函数可变参数定义及其参数传递方式...

    Python函数可变参数定义及其参数传递方式详解 python中 函数不定参数的定义形式如下 1. func(*args) 传入的参数为以元组形式存在args中,如: def func(*args): ...

  7. python3中unicode怎么写_详解python3中ascii与Unicode使用

    这篇文章主要为大家详解python3中ascii与Unicode使用的相关资料,需要的朋友可以参考下# Auther: Aaron Fan ''' ASCII:不支持中文,1个英文占1个字节 Unic ...

  8. python调用cmd命令释放端口_详解python调用cmd命令三种方法

    目前我使用到的python中执行cmd的方式有三种 使用os.system("cmd") 该方法在调用完shell脚本后,返回一个16位的二进制数,低位为杀死所调用脚本的信号号码, ...

  9. python中有那几种赋值_详解Python列表赋值复制深拷贝及5种浅拷贝

    概述 在列表复制这个问题,看似简单的复制却有着许多的学问,尤其是对新手来说,理所当然的事情却并不如意,比如列表的赋值.复制.浅拷贝.深拷贝等绕口的名词到底有什么区别和作用呢? 列表赋值 # 定义一个新 ...

最新文章

  1. Spring Boot(十一)Redis集成从Docker安装到分布式Session共享
  2. 上热搜了!“学了Python6个月,竟然找不到工作!”
  3. 阿里2018营收2502亿元,云计算业务增幅超100%
  4. 链表问题15——将搜索二叉树转换成双向链表(方法二)
  5. JavaScript 开发者最期待的年度大会,惊喜不断,错过还要等好久!
  6. CentOS系统安装(上):图形/文本界面安装
  7. [Redux-Observable Unit Testing] Mocking an ajax request when testing epics
  8. php execute 更新不变,php – Doctrine executeUpdate数组参数
  9. gearman初探(一、编译和安装)
  10. T24412 Cup#182-3 洞穴之旅
  11. php为图片添加渐变背景,HTML_CSS实例:通过定义渐变边框给图片加阴影,一般我们可以使用背景图的方 - phpStudy...
  12. 【Elasticsearch】elasticsearch allocation 分析
  13. eclipsevue代码怎么运行_打了多年的单片机调试断点到底应该怎么设置? | 颠覆认知...
  14. python写文件flush_python读写文件write和flush
  15. 我碰到的到现在为止,还没有找到比较好的解决方法的sps问题
  16. 约瑟夫环c语言代码顺序存储,详解约瑟夫环问题及其相关的C语言算法实现
  17. 人在烟火间(外两章)
  18. python做事务所审计收费标准_会计师事务所审计收费标准?2019审计报告收费标准...
  19. 【暑假阅读推荐书目】历史篇·中国史
  20. 抢票软件之——py12306使用指南

热门文章

  1. 教你如何切换淘宝镜像
  2. 你都这么拼了,面试官TM怎么还是无动于衷?
  3. 新的RA Group勒索软件针对美国组织进行双重勒索攻击
  4. 时间转换datetime
  5. Linux内核高端内存管理
  6. 分享一个神奇的空间数据库
  7. 【流量分析】如何从大量数据会话中识别出视频流
  8. Win11系统更新后网络速度变的很慢怎么办?
  9. 满清雍正皇帝严惩贪官污吏的狠招(转)
  10. [SV]SystemVerilog Mailbox