自动修补PYTHONPATH(使用结构任务时)

2024-10-03 23:22:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我可以在pythorth函数中显式地添加一个基于pythorth的函数来添加当前模块的相关注释,这样就可以在pythorth的函数中显式地添加到pythorth的函数中,而不必在这个模块中添加相关的注释

def patch_python_path(f):
    @wraps(f)       
    def wrap(*args, **kwargs):
        ROOT = os.pathsep.join([os.path.abspath(os.path.dirname(__file__))])
        if not os.environ.has_key("PYTHONPATH"):
            os.environ["PYTHONPATH"] = ""
        if not (ROOT in os.environ["PYTHONPATH"].split(":")):
            os.environ["PYTHONPATH"] = "%s:%s" % (os.environ["PYTHONPATH"], ROOT)
        if not ROOT in sys.path:
            sys.path.append(ROOT)
        return f(*args, **kwargs)
    return wrap

下面是我如何使用它:

^{pr2}$

这种方法有什么我不知道的重大问题吗?在


我的目标如下:

  • 我想要一个自包含的引导程序,用户可以立即使用而不需要任何额外的env操作
  • 我还假设用户可以更改引导包的名称,因此所有导入都必须保持相对

[编辑]我实际上意识到,我所面临的问题更多地与Fabric运行任务的方式有关,而不是纯Python模块导入。如果我试图从pythonshell(而不是fab task1)运行一个任务,那么所有导入都会得到正确的解析,而不需要任何补丁。通过fab运行任务会导致导入错误


Tags: 模块path函数inifosdefenviron
2条回答
  1. os.environ是全局的。你在修改它,而不是事后再修改它。因此,在对任何函数执行@patch_python_path操作之后,您现在已经对定义的所有其他内容(包括其他模块和顶层脚本)执行了等效操作。在
  2. sys.path也是全局的,而且您要修改它而不是恢复它。在
  3. 您不应该同时修改PYTHONPATH和{}。(尤其是前者,你通常不需要它。)
  4. 您将.添加到PYTHONPATH,但是{}添加到{}。如果您曾经做过都需要修改这两者,那么在os.chdir()之后,一切都将停止工作,这将有效地改变PYTHONPATH,但不会改变{}。在
  5. 任何包装的函数都将丢失其docstring、名称等;请在wrap函数上使用@functools.wraps。在

这些都只是你的实现中的问题,而没有考虑到它是否是一个好主意。在

人们想要这样做的最常见的原因是(a)使pythonx.Y包像pythonv.W一样工作,(b)允许从源代码树导入包,以便与安装后导入包相同,甚至可以从解释器shell导入。前者可能是个坏主意;后者很方便,但还有其他方法可以实现。如果你有一些不同的更高层次的目标,你必须告诉我们这个目标是什么,然后别人才能告诉你这是否是实现它的最佳方法。在

您只需将当前路径添加到sys.path

import sys
def patch_python_path(f):
    def wrap(*args, **kwargs):
        if not '.' in sys.path:
            sys.path.append('.')
        return f(*args, **kwargs)

    return wrap

相关问题 更多 >