我有几个app' -modules(由主应用程序启动) 以及具有某些功能的实用程序模块:
my_utility/
├── __init__.py
└── __main__.py
apps/
├── app1/
│ ├── __init__.py
│ └── __main__.py
├── app2/
│ ├── __init__.py
│ └── __main__.py
...
main_app.py
应用程序正在这样启动(通过主应用程序):
python3 -m <app-name>
我需要提供一些关于每个应用程序的元信息(与模块相关),main_app
和应用程序本身可以读取这些信息:
应用/ APP1 / __初始化__吡啶:
meta_info = {'min_platform_version': '1.0',
'logger_name': 'mm1'}
...并像这样使用它:
应用/ APP1 / __主__吡啶:
from my_utility import handle_meta_info
# does something with meta_info (checking, etc.)
handle_meta_info()
main_app.py :
mod = importlib.import_module('app1')
meta_inf = getattr(mod, 'meta_info')
do_something(meta_inf)
我不知道如何从应用内访问meta_info
。我知道我可以
import
模块本身并访问meta_info
:
应用/ APP1 / __主__吡啶:
import app1
do_something(app1.meta_info)
但这只有在我知道模块的名称时才有可能。从另一个模块内部 - 例如my_utility
我不知道如何访问首先启动的模块(或其名称)。
my_utility / __主__吡啶:
def handle_meta_info():
import MAIN_MODULE <-- don't know, what to import here
do_something(MAIN_MODULE.meta_info)
我不知道如何在应用程序的流程中访问meta_info
(通过python3 -m <name>
启动,但是来自另一个不知道其名称的模块已启动的&#39; root&#39;模块
在调用元信息函数时始终提供模块名称(错误,因为它冗长且冗余)
from my_utility import handle_meta_info
handle_meta_info('app1')
将meta_info
添加到__builtins__
(通常不利于污染全球空间)
解析命令行(丑陋)
分析import my_utility
上的调用堆栈(危险,丑陋)
能够访问&#34; main&#34;会很高兴。模块全局空间或知道它的名称(导入)
my_utility / __主__吡啶:
def handle_meta_info():
do_something(__main_module__.meta_info)
OR
def handle_meta_info():
if process_has_been_started_as_module():
mod = importlib.import_module(name_of_main_module())
meta_inf = getattr(mod, 'meta_info')
do_something(meta_inf)
有什么想法吗?
我目前的(血腥)解决方案:
在my_utility
内部我使用psutil
来获取模块已启动的命令行(为什么不sys.argv
?Because)。在那里我提取模块名称。这样我将所需的元信息附加到my_utility
(所以我只需加载一次)。
my_utility / __初始化__吡啶:
def __get_executed_modules_meta_info__() -> dict:
def get_executed_module_name()
from psutil import Process
from os import getpid
_cmdline = Process(getpid()).cmdline
try:
# normal case: app has been started via 'python3 -m <app>'
return _cmdline[_cmdline.index('-m') + 1]
except ValueError:
return None
from importlib import import_module
try:
_main_module = import_module(get_module_name())
return import_module(get_executed_module_name()).meta_info
except AttributeError:
return {}
__executed_modules_meta_info__ = __get_executed_modules_meta_info__()