Python中的全局初始化函数和全局常量,不使用sys.path.append()

时间:2017-12-06 16:24:44

标签: python

我的用例如下:

  • 可以单独运行的几个脚本
  • 一个可以运行所有脚本的“母亲”脚本
  • 每个脚本都有它使用的全局变量(指向特定位置的路径,所有脚本使用的常量)
  • 其中一些全局变量输入到settings.yaml文件中,该文件动态加载yaml.load()
  • 有几个人正在运行系统,我们希望避免环境变量或任何类型的低级路径设置

用例满意

import settings

在每个导出模块的开头。

settings.py脚本是我们的'initialize'脚本,用于加载和创建用于所有模块的变量,例如:

import os
import yaml
from utils import create_dir

input_f = open("settings.yml")
settings = yaml.load(input_f.read())
input_f.close()

TOHELLO = settings['TOHELLO']
TOBONJOUR = settings['TOBONJOUR']

#check for needed directories and create if necessary
create_dir(TOHELLO)
create_dir(TOBONJOUR)

'母模块'export_all.py使用Subprocess.Popen()按顺序运行所有脚本。

最初所有文件都在根目录中:

+--settings.py
+--settings.yml
+--export_foo1.py
+--export_foo2.py
+--export_foo3.py
+--export_foo4.py
+--export_bar1.py
+--export_bar2.py
+--export_bar3.py
+--export_bar4.py
+--export_all.py
然而,随着时间的推移,这变得混乱,我们决定对其进行重组:

+--settings.py
+--settings.yml
+--Foo
+  +--export_foo1.py
+  +--export_foo2.py
+  +--export_foo3.py
+  +--export_foo4.py
+--Bar
+  +--export_bar1.py
+  +--export_bar2.py
+  +--export_bar3.py
+  +--export_bar4.py
+--export_all.py

然后一切都崩溃了。

我们发现人们只能对模块中的 或特别是在sys.path中使用'import'。

我们提出的解决方案包括将这个美容插入我们所有脚本的顶部:

PACKAGE_PARENT = os.path.join('..','..')
SCRIPT_DIR = os.path.dirname(os.path.realpath(os.path.join(os.getcwd(), os.path.expanduser(__file__))))
sys.path.append(os.path.normpath(os.path.join(SCRIPT_DIR, PACKAGE_PARENT)))

但这对我们来说似乎有些过分。

我们试过了

from settings import functionname

但是这不会运行从yaml文件生成常量的代码

另外,我们尝试在每个目录中挤压__init.py__中的import,但Subprocess.Popen()无效。

我们有点缺少一种pythonesque方式来获得一些全局常量,以及一个只运行一次的初始化脚本(即使'母'脚本正在运行)。

是我们,还是蟒蛇在这里奇怪而丑陋?

2 个答案:

答案 0 :(得分:0)

您需要将目录转换为模块:https://docs.python.org/2/tutorial/modules.html#packages

允许你使用这样的结构:

from foo import export_foo1

或使用:

from ..bar import export_bar1

如果您在子文件夹中

https://docs.python.org/2/tutorial/modules.html#intra-package-references

答案 1 :(得分:0)

我不确定究竟是什么问题,但您可以选择以下几个选项:

  1. 最好的方法是引用您的脚本,就好像它们是包的子模块一样。在这种情况下,如果从export_all.py所在的目录运行所有脚本,一切都应该有效。唯一的变化是您应该将它们作为模块运行,而不是作为脚本运行:

    $ python export_all.py
    

    $ python -m Foo.export_foo
    
  2. 您可以使用PYTHONPATH环境变量将sys.path的其他路径传递到您的脚本。该变量将由子进程继承。

  3. 假设您在虚拟环境中运行脚本,可以在site-packages目录中放置.pth文件,其中包含FooBar目录的绝对路径。每次使用sys.path启动脚本而没有python切换时,路径都会添加到-S。您可以在标准site模块的文档中阅读有关.pth文件的信息。