如何从其他模块访问当前执行模块的属性?

时间:2016-11-15 09:53:50

标签: python module

我有几个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.argvBecause)。在那里我提取模块名称。这样我将所需的元信息附加到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__()

0 个答案:

没有答案