【问题标题】:Convert module to dict将模块转换为字典
【发布时间】:2016-06-06 12:40:19
【问题描述】:

我想做以下事情(python3):

在模块settings.py:

message = 'Hello'

在模块__main__.py:

from . import settings


def dict_from_module(module):
    ...
    return d

print(dict_from_module(settings))

运行它应该产生:

{'message': 'hello'}

是否有将模块转换为字典的规范方法?

编辑

使用vars(settings) 可以提供大量内部信息:

{   
    '__builtins__': {
        ...
    },
    '__cached__': 'xxx/__pycache__/settings.cpython-34.pyc',
    '__doc__': None,
    '__file__': 'xxx/settings.py',
    '__loader__': <_frozen_importlib.SourceFileLoader object at 0x7f87fc192518>,
    '__name__': 'xxx.settings',
    '__package__': 'xxx',
    '__spec__': ModuleSpec(...),
    'message': 'bye'
}

我不想要/不需要。我可以将其过滤掉(通过删除以__ 开头的键),但如果有可接受的方法,我想避免乱搞。

【问题讨论】:

  • @vaultah:谢谢,但这提供了很多我不想要/不需要的内部属性
  • 我认为没有不包括以某种方式过滤掉预定义值的解决方案。另外,您需要解决边界情况,例如当模块声明变量 __doc__ 时该怎么办。

标签: python python-3.x dictionary module namespaces


【解决方案1】:

希望这会有所帮助!

def dict_from_module(module):
    context = {}
    for setting in dir(module):
        # you can write your filter here
        if setting.islower() and setting.isalpha():
            context[setting] = getattr(module, setting)

    return context

【讨论】:

  • +1 这不是一个复杂或花哨的解决方案,但对于设置对象,这在大多数情况下解决了问题,如 OP。
  • 我的方式:module_to_dict = lambda module: {k: getattr(module, k) for k in dir(module) if not k.startswith('_')}
【解决方案2】:

另一种选择是将__all__ 与您一起转换为dict 的模块一起使用。 例如,我导出的模块是

# mylib.py

__all__ = ['square']

def square(x):
    return x ** 2

您可以像这样轻松将此模块转换为 dict:

def module_to_dict(module):
    return {key: getattr(module, key) for key in module.__all__}

给出以下输出:

>>> import mylib
>>> module_to_dict(mylib)
{'square': <function square at 0x03C39B28>}

【讨论】:

    【解决方案3】:

    我使用 python 文件作为配置文件,其中包含常量和可计算属性。为了与一些网络服务接口,我需要它是可序列化的(例如像字典一样)。基于@heykarimoff 的解决方案,我使用startswith("_")isinstance(v, ModuleType): 过滤掉导入的模块,这样它们就不会出现在字典中。

    def dict_from_module(module):
        context = {}
        for setting in dir(module):
            if not setting.startswith("_"):
                v = getattr(module, setting)
                if not isinstance(v, ModuleType):
                    context[setting] = getattr(module, setting)
        return context
    

    【讨论】:

      【解决方案4】:
      import inspect
      from itertools import takewhile
      
      import .settings
      
      dict(takewhile(lambda i: i[0] != '__builtins__', inspect.getmembers(settings)))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-29
        • 2011-09-19
        • 2019-02-06
        • 2019-11-15
        • 2018-08-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多