我继承了相当多的python代码,并且它是以下代码片段,它将父目录的文件路径添加到系统路径。
from os.path import join, dirname
sys.path.insert(0, join(dirname(sys.argv[0]), "..\\"))
from utilities import find, execute
我对此的理解是它增加了搜索路径的路径。在程序运行期间,在搜索路径中添加了许多路径,并且可能使其变慢。因为每个文件都添加了它自己的父目录。
我更喜欢语法
from scm_tools.general.utilities import find, execute
因为这更容易理解而且代码更少。如果我正在移动代码,但这可能会影响到一个包中。
我是否正确地假设在一个包中,后一种语法是更加pythonic的做事方式?
或者它真的不重要因为引擎盖蟒蛇正在做一些魔术?
答案 0 :(得分:3)
尽可能使用相对导入:
from ..utilities import find, execute
这要求您保留在模块空间内,这意味着您遍历的每个目录都需要__init__.py
文件。
有些情况会发生故障,例如,如果您的测试目录不在模块结构中。在这些情况下,您需要编辑路径,但不应像上面的示例那样盲目地编辑路径。
在代码启动之前添加到PYTHONPATH
环境变量,这样您就可以始终引用目录的根目录,或者只添加sys.path
中尚未添加的路径,并尝试避免添加任何内容模块根源。
对于您希望分发的代码,PYTHONPATH
更改有点冒险。很容易在PYTHONPATH
中进行无法控制的更改,或者您无法以转移到分布式代码的方式定义该添加。它还增加了一个令人烦恼的模块要求,其他人必须处理 - 所以保留这个要求来添加你想要包含的整个模块,比如自定义站点包目录。在这种情况下使用virtualenv总是更好 。
如果你确实需要更改sys.path
内部代码,你应该尝试至少避免在整个地方破坏它,否则当它出错时你会很难解决它。为避免这种情况,请尝试仅添加根模块路径,以便始终以root.submodule.desiredmodule
模式导入。另外,在将路径插入sys.path
之前检查路径是否已存在,以避免很长sys.path
秒。在我的测试目录中,我经常有一个可导入的文件,将sys.path
修复为我正在测试的目录结构的根目录:
# Add parent import capabilities
parentdir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
if parentdir not in sys.path:
sys.path.insert(0, parentdir)