代码之家  ›  专栏  ›  技术社区  ›  Gnudiff

有没有更优雅的方式来引用脚本的当前目录?

  •  0
  • Gnudiff  · 技术社区  · 6 年前

    我有开发环境和产品来运行各种 Python 使用的脚本 crontab .

    在开发环境中,我通常从脚本目录中的命令行测试脚本,例如 "python myscript.py" . 现在,一些脚本从 JSON 脚本目录的相同或子目录中的文件。 因此,在dev中,我可以这样引用文件:

    printconf = Config('printing.json')
    

    然而,一旦脚本准备好进行生产,它就会被投入使用 克朗塔布 克朗塔布 从中调用脚本 root 因此打破了上述界限。

    此外,开发和生产显然在文件系统中的不同位置,所以我甚至不能使用绝对路径,因为它们不一样。

    如中所述 How can I find script's directory with Python? ,我可以用各种方法找到当前目录下的文件。他们的意思是,但是,额外的处理,我想知道, 如果有的话 python 版本可能有(或可能已经计划好)任何其他内置方式来判断文件必须相对于运行脚本的目录找到?差不多 __location__ ?

    本质上,一些对文件引用有用的东西,比如导入模块,已经可以了。

    此外,我还尝试添加一个全球 __地点__ 可变通孔 sitecustomize.py ,但这根本不起作用。

    网站定制。py:

    if '__file__' in globals():
        import os
        _location_ = os.path.join(os.getcwd(), os.path.dirname(__file__))
    

    但这也不行,因为: - __地点__ 未传递到脚本, -及 __file__ 网站定制。py

    0 回复  |  直到 6 年前
        1
  •  0
  •   Mihai    6 年前

    首先也是最重要的一点是,您的开发环境和Prod环境不应该有太大的差异。这意味着,为了保持一致性,您应该对这两种应用使用相同的设置(文件系统、库等)。这样你的大部分问题都会消失。 如果你这样做,那么使用硬编码路径是安全的。

    其他选项(不可避免地涉及一些处理,但不应成为交易破坏者):

    1. 使用 os.getcwd() __file__ ,正如你所建议的。
    2. 运行脚本时使用特定参数(例如: $SCRIPT_PATH/myscript.py PROD )并在脚本中基于此选择路径。
    3. 只为script init使用一个专用的配置文件,将其放在DEV和PROD上的同一位置(我建议在 /etc/$PROJECT_NAME )并使用特定参数运行脚本(如上所述)。

    以上所有方法都无法防止与一致性相关的其他问题,这让我强调,您应该考虑在Dev设置(和/或Prod,如果可能的话)中使用Docker或Vagrant。

        2
  •  0
  •   Gnudiff    5 年前

    当我回顾这个问题时,很明显我提供了太多错误的背景,而相关的背景太少。在测试实际解决方案时,我决定不重写问题,而是在答案中加入正确的上下文。

    大多数问题都是因为我想确定文件B相对于脚本A的路径,而实际调用文件B时使用的是系统范围的模块C(从脚本A调用),该模块位于完全不同的位置,如下所示:

    #module C (system-wide in /usr.../site-packages
    import os
    class Config()
       ...
       def load(file_name):
        # needs to be relative to calling script's dir, not module's!
        real_file_name=os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])),file_name)
        ...
    
    #script-A.py ( in /var/scripts/projectA )
    from C import Config
    conf=Config()
    conf.load('file-in-projectA-dir.json')
    # finds /var/scripts/projectA/file-in-projectA-dir.json
    # regardless of cwd
    

    因此,这对以下两方面都有效:

    cd /
    python3 /var/scripts/projectA/script-A.py
    #and:
    cd /var/scripts/projectA/
    python3 script-A.py
    #etc
    

    正如您所看到的,这只是因为script-A是作为第一个参数从命令行调用的。然而,这是我的主要用例。不确定,否则会有什么效果。