在本文中,我们将为您详细介绍隐式相对导入在Python中如何工作?的相关知识,并且为您解答关于隐式对象的作用的疑问,此外,我们还会提供一些关于Python3中的相对导入无法正常工作、python包的相
在本文中,我们将为您详细介绍隐式相对导入在Python中如何工作?的相关知识,并且为您解答关于隐式对象的作用的疑问,此外,我们还会提供一些关于Python 3中的相对导入无法正常工作、python 包的相对导入与绝对导入使用、Python 相对导入、Python-如何在Python中进行相对导入?的有用信息。
本文目录一览:- 隐式相对导入在Python中如何工作?(隐式对象的作用)
- Python 3中的相对导入无法正常工作
- python 包的相对导入与绝对导入使用
- Python 相对导入
- Python-如何在Python中进行相对导入?
隐式相对导入在Python中如何工作?(隐式对象的作用)
假设我有以下文件,
pkg/pkg/__init__.pypkg/main.py # import stringpkg/string.py # print("Package''s string module imported")
现在,如果我跑步main.py
,它说"Package''s string module imported"
。
这是有道理的,并且按照此链接中的以下语句运行:
“它将首先在包的目录中查找”
假设我稍微修改了文件结构(添加了一个核心目录):
pkg/pkg/__init__.pyplg/core/__init__.pypkg/core/main.py # import stringpkg/string.py # print("Package''s string module imported")
现在,如果我运行python core/main.py
,它将加载内置string
模块。
同样在第二种情况下,如果必须遵守“ 它将首先在软件包的目录中查找 ” 这样 的语句 ,是否
应该加载本地文件,string.py
因为pkg
它是“软件包的目录”?
我的术语“包目录”的意义是 明确 的 根文件夹 一个的 集合 与文件夹__init__.py
。因此,在这种情况下,
pkg 是“程序包目录”。它适用main.py
于子目录,也适用于子目录中的文件,例如,core/main.py
因为它是此“包”的一部分。
这在技术上正确吗?
PS:#
代码段后面的内容是文件的实际内容(没有前导空格)。
答案1
小编典典软件包是带有__init__.py
文件的目录,是的,并且 在模块搜索路径上找到时
作为模块加载。所以pkg
只有一个包,你可以导入和处理作为一个整体 ,如果父目录是模块搜索路径上 。
但是通过将pkg/core/main.py
文件作为 脚本
运行,Python将pkg/core
目录添加到了模块搜索路径,而不是的父目录pkg
。__init__.py
现在,您的模块搜索路径上确实有一个文件,但这不是定义包的原因。您只有一个__main__
模块,没有其他任何包关系,并且您不能依赖隐式相对导入。
您有三种选择:
不要将包中的文件作为脚本运行。将脚本文件 放在 包 之外 ,并根据需要导入脚本。你可以把它 旁边 的
pkg
目录,或者确保pkg
目录首次安装到一个目录已经是模块搜索路径,或让你的脚本计算添加到正确的道路sys.path
。使用
-m
命令行开关可以像运行脚本一样运行模块。如果您使用python -m pkg.core
Python,则会查找__main__.py
文件并将其作为脚本运行。该-m
交换机将增加当前工作目录到你的模块搜索路径,所以你可以使用这个命令时,你在正确的工作目录,这样就可以了。或者将软件包安装在模块搜索路径上已经存在的目录中。让您的脚本将正确的目录添加到模块搜索路径(基于
os.path.absolute(__file__)
以获取当前文件的路径)。考虑到您的脚本 始终 被命名为__main__
,并且导入pkg.core.main
将添加另一个独立的模块对象;您将拥有两个单独的命名空间。
我也 强烈
建议不要使用隐式相对导入。您可以通过添加嵌套的软件包或具有相同名称的模块来轻松地屏蔽顶级模块和软件包。如果您尝试在包内使用,将pkg/time.py
在standard-
librarytime
模块之前找到。相反,请使用 显式 相对模块引用的Python
3模型;添加到您的所有文件,然后用于明确指出从何处导入模块。import time``pkg
__from __future__ importabsolute_import``from . import <name>
Python 3中的相对导入无法正常工作
我有以下目录:
mydirectory
├── __init__.py
├── file1.py
└── file2.py
我在file1.py中定义了一个函数f。
如果在file2.py中,我这样做
from .file1 import f
我收到以下错误:
SystemError:父模块“”未加载,无法执行相对导入
为什么?以及如何使其工作?
python 包的相对导入与绝对导入使用
一、错误使用,造成的错误描述如下:
ModuleNotFoundError: No module named ''__main__.operation''; ''__main__'' is not a package
ModuleNotFoundError: No module named ''operation''
ValueError: attempted relative import beyond top-level package
二、实例目录结构:
cur_path
│
├─packages
│ ├─__init__.py
│ ├─ui.py
│ │
│ ├─operation
│ │ ├─__init__.py
│ │ ├─mixed_operation.py
│ │ └─simple_operation.py
│ │
│ └─util
│ ├─__init__.py
│ ├─add.py
│ ├─div.py
│ ├─mul.py
│ └─sub.py
└─main.py
三、示例:
1、main.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from packages.ui import main
if __name__ == "__main__":
main()
2、packages/ui.py
from .operation.mixed_operation import mix
def main():
mix()
if __name__ == "__main__":
main()
3、packages/operation/mixed_operation.py
from .simple_operation import *
def mix():
num = one_add_two() + three_mul_four() + five_sub_six() + seven_sub_eight()
print("1 + 2 + 3 * 4 + 5 - 6 + 7 / 8 = ", num)
4、packages/operation/simple_operation.py
from ..util.add import add
from ..util.sub import sub
from ..util.mul import mul
from ..util.div import div
def one_add_two():
return add(1, 2)
def three_mul_four():
return mul(3, 4)
def five_sub_six():
return sub(5, 6)
def seven_sub_eight():
return div(7, 8)
__all__ = ["one_add_two", "three_mul_four", "five_sub_six", "seven_sub_eight"]
5、packages/util/add.py
def add(a, b):
return a + b
6、packages/util/div.py
def div(a, b):
return a / b
7、packages/util/mul.py
def mul(a, b):
return a * b
8、packages/util/sub.py
def sub(a, b):
return a - b
四、运行方式:
1、正确运行方式:
python -m packages.ui
python main.py
2、错误运行方式以及错误描述
# 直接运行的脚本中不能含有相对导入
python packages/ui.py
Traceback (most recent call last):
File "packages/ui.py", line 6, in <module>
from .operation.mixed_operation import mix
ModuleNotFoundError: No module named ''__main__.operation''; ''__main__'' is not a package
################################
# 模块方式,引入当前需要添加.号
# ui.py中的from后没有.
python -m packages.ui
packages\ui.py", line 3, in <module>
from operation.mixed_operation import mix
ModuleNotFoundError: No module named ''operation''
Python 相对导入
假设有如下层次包目录
- run.py作为顶层模块执行导入A.spam时
- run.py的__name__ 等于 __main__
- spam.py的__name__ 等于 A.spam
- A成为顶层的包,所以相对导入最多只能访问到A,A之外的层次结构是不可见的
- main.py作为顶层模块执行导入mypackage.A.spam是
- main.py的 __name__ 为 __main__
- spam.py的__name__ 为 mypackage.A.spam
- mypackage成为顶层包,相对导入作用域扩大,B/包对spam.py可见
-
如果将run.py当作顶层执行模块
-
A/ 和 B/ 将成为 toplevel package 顶层包 A/中的模块不能用相对导入来导入B/包中的模块,因为不能越过顶层包。
-
A/、B/ 包中的目录可以导入本包中及以下的模块
-
如果将main.py当作顶层执行模块
-
mypackage/成为顶层包,A/可以访问到B/包,不会出现 ValueError: attempted relative import beyond top-level package
Python-如何在Python中进行相对导入?
想象一下这个目录结构:
app/ __init__.py sub1/ __init__.py mod1.py sub2/ __init__.py mod2.py
我正在编码mod1
,我需要从中导入一些东西mod2
。我该怎么办?
我尝试过,from ..sub2 import mod2
但是得到了“未打包的相对导入尝试”。
我四处搜寻,但只发现"sys.path manipulation"
骇客。有没有一种干净的方法?
答案1
小编典典每个人似乎都想告诉你应该做什么,而不仅仅是回答问题。
问题是你通过将mod1.py
作为参数传递给解释器而将模块作为__main__
运行。
从PEP 328:
相对导入使用模块的__name__
属性来确定该模块在包层次结构中的位置。如果模块的名称不包含任何软件包信息(例如,将其设置为''__main__''
),则相对导入的解析就好像该模块是顶级模块一样,无论该模块实际位于文件系统上的哪个位置。
在Python 2.6中,他们添加了相对于主模块引用模块的功能。 PEP 366描述了更改。
更新:根据Nick Coghlan的建议,推荐的替代方法是使用-m开关运行软件包中的模块。
今天关于隐式相对导入在Python中如何工作?和隐式对象的作用的分享就到这里,希望大家有所收获,若想了解更多关于Python 3中的相对导入无法正常工作、python 包的相对导入与绝对导入使用、Python 相对导入、Python-如何在Python中进行相对导入?等相关知识,可以在本站进行查询。
本文标签: