Python 3软件包和脚本中导入的最佳实践
问题描述:
考虑以下简单的文件夹结构:
Consider this simple folder structure:
root
Package1
x.py
y.py
Package2
z.py
Examples
main.py
现在我们的要求是:
- x.py需要导入y.py
- z.py需要导入y.py
- main.py需要导入y.py和z.py
下面是有效的方法:
x.py
import y
def x():
y()
y.py
def y():
pass
z.py
import package1.y as y
def z():
y.y()
main.py
import sys
from os import path
sys.path.append( path.dirname( path.dirname( path.abspath(__file__) ) ) )
import package1.y as y
import package2.z as z
y.y()
z.z()
问题:
- 这是在Python 3中设置导入的最佳和推荐方法吗?
- 我真的不喜欢在
main
中更改sys.path
,因为它强烈绑定了关于程序包位置 inside 代码文件的假设.有什么办法解决吗? - 我也真的不喜欢
import package1.y as y
中多余的as y
部分.有什么办法解决吗?
- Is this the best and recommended way to setup imports in Python 3?
- I really don't like changing
sys.path
inmain
because it strongly binds assumptions about package locations inside code file. Is there any way around that? - I also really don't like superfluous
as y
part inimport package1.y as y
. Is there any way around that?
答
和往常一样,有两个单独的步骤:
As always, there are two separate steps:
- 您针对包的抽象名称空间编写代码,该名称空间包含
package1
和package2
(以及sys
,os
,等.) ,但不是不是包的示例"(因为main.py
不是模块). - 您可以在运行任何代码之前 适当地设置
sys.path
.如果是您自己的代码(未安装),则有您可以放置的地方,或者您可以编写简单的Shell脚本包装器为python
流程设置PYTHONPATH
.
- You write the code against the abstract namespace of packages, which contains
package1
andpackage2
(andsys
,os
, etc.), but not "Examples" which is not a package (becausemain.py
is not a module). - You set
sys.path
appropriately before any of your code ever runs. If it's your own (uninstalled) code, there are places you can put it, or you can write an easy shell script wrapper to setPYTHONPATH
for yourpython
process.
所以您的问题的答案是
- 在
x.py
中,您编写from . import y
. (Python 2支持此功能,而Python 3支持此功能.) - 如何设置
sys.path
取决于包装/环境系统.传统方式是为python
进程设置PYTHONPATH
环境变量,但是还有其他方式涉及诸如site
模块之类的东西. -
from package1 import y
是通常只给事物命名一次的方法.
- In
x.py
you writefrom . import y
. (Python 2 supports this and 3 requires it.) - How you set
sys.path
depends on your packaging/environment system. The traditional way is to set thePYTHONPATH
environment variable for thepython
process, but there are other ways involving things like thesite
module. -
from package1 import y
is the usual way to name things only once.