Python: Do relative imports mean you can't execute a subpackage by itself?
我最近移植了我的Python项目以在Python 3.1上运行。 为此我必须在我的项目的子模块和子包中采用相对导入的策略。 我不这样做,现在项目本身有效,但我注意到我无法执行其中的任何子包或子模块。 如果我尝试,我得到"builtins.ValueError:在非包中尝试相对导入"。 我只能导入整个项目。
这是正常的吗?
是的,这是正常的。 如果你想执行一个也是包的一部分的模块(本身就是一件奇怪的事情),你需要进行绝对导入。 当您执行模块时,从解释器的角度来看,它不是包的一部分,而是__main__模块。 所以它不知道相关包的位置。
执行此操作的标准方法是在包中包含函数,以及调用函数的单独可执行脚本,因为这使您可以将可执行脚本放在模块外部,例如在/ usr / bin中
-
哇,我发现这个哲学很奇怪。例如,我在我的项目中有一个包life。它的绝对路径是garlicsim.bundled.simulation_packages.life。我本来希望能够自己运行它,因为它不依赖于garlicsim中的任何东西。为什么我不能自己运行它?
-
1.如果它不依赖于大蒜素中的任何东西,那么为什么它在大蒜素中呢? 2.为什么你不能自己运行它?您可以单独运行它,但您需要具有绝对导入,即from garlicsim.bundled.simulation_packages.life import whatever。 3.你觉得奇怪的哲学是什么?我没有提到任何哲学,所以我不知道"这个"哲学是什么。
-
1.它只是捆绑在一起。但我可以采取另一个例子,garlicsim.asynchronous_crunching.crunchers,这是garlicsim依赖的子包,但它不依赖于garlicsim。 (2)如果有一天我想将它移动到另一个包中,为什么我不能在没有编辑导入行的大惊小怪的情况下? (3)也许我应该说"政策"而不是"哲学"。这种态度,能够(a)独立执行包,或(b)轻松地将其移植到其他包,但不能两者兼而有之。
-
吉兹。人们争论今天的答案是什么意思? :-)你不能轻易移动它吗?搜索和替换不容易吗?无论如何,你需要在garlicsim中进行搜索和替换。 ---没有这样的政策。然而,不可能做你想做的事,但是再一次,没有令人信服的理由去做。 ---如果你不同意Python 3中相对导入的变化(并且有很好的理由让它发生变化),而不是在Python-dev上抱怨,并准备好受到攻击,那么:-)
您可以使用python解释器的-m标志在子包中运行模块(甚至可以在3.1中使用包)。
-
我要说你必须使用-m开关;不是你能做到的。我喜欢直接调用python文件,因为我不需要记住开关,我的shell很好地自动完成。
-
如果您对从子模块运行可执行python脚本感兴趣,请参阅此答案:stackoverflow.com/a/11537218/730150
我有同样的问题,我认为-m开关太难了。
相反,我用这个:
1 2 3 4 5 6 7
| try:
from . import bar
except ValueError:
import bar
if __name__ =="__main__":
pass |
-
在python 2.7中不推荐使用隐式相对导入并将其删除。
-
Arron,你是对的,但我不知道这是如何改变我的解决方案的。这适用于任何python 2.5-3.1。
-
不,这在3.x中不起作用。它在2.7+中删除,包括3.0-3.1。
-
@Arron,你试过上面的代码并且运行失败吗?我猜不是,我确实在Python 2.6,2.7和3.1上运行它。您正在谈论的更改仅影响import bar这样的行的行为,这就是为什么我提出这种用法,以说服Python更喜欢从当前目录加载bar模块(如果可能)。
-
@AaronGallagher,你是什么意思?当然,我可以从主脚本或交互式shell导入名为bar.py的工作目录中的文件。我不能从模块中做到这一点。
-
对于python3兼容性,except (ValueError, SystemError)似乎有效。