【问题标题】:Indented namespacing with pythonpython缩进命名空间
【发布时间】:2019-07-26 14:38:31
【问题描述】:

我有一个包含大量路径的配置文件,我想以某种方式组织它们。所以我决定使用types.SimpleNamespace 这样做:

paths = SimpleNamespace()
paths.base = '...'
paths.dataset.encoded = '...'

我得到了:

AttributeError: 'types.SimpleNamespace' object has no attribute 'dataset'

我尝试定义paths.dataset,尽管我不需要它但它不起作用:

paths = SimpleNamespace()
paths.base = '...'
paths.dataset = '...'
paths.dataset.encoded = '...'
AttributeError: 'str' object has no attribute 'encoded'

我也试过这个:

_ = {
    'base': '...',
    'dataset': {
        'encoded': '...',
    }
}
paths = SimpleNamespace(**_)

结果如下:

>>> paths.dataset.encoded  # Error
AttributeError: 'dict' object has no attribute 'encoded'
>>> paths.dataset['encoded']  # works
'...'

这意味着 SimpleNamespace 仅适用于一层命名空间,对吗?

还有其他解决方案吗?我的意思是一个解决方案,而不是像这样对每一层使用 SimpleNamespace:

dataset = SimpleNamespace()
dataset.encoded = '...'

paths = SimpleNamespace()
paths.base = '???'
paths.dataset = dataset

>>> paths.base
'???'
>>> paths.dataset.encoded
'...'

有什么想法吗?

【问题讨论】:

  • 如果您期望配置的特定形状,为什么不将其定义为实际类而不是任意可扩展的命名空间?
  • @mistermiyagi 我试过了,但由于我对课程知之甚少而失败了。你能举个例子吗?提前致谢。

标签: python types namespaces


【解决方案1】:

我想出了这个解决方案:


def create_namespace(dictionary: dict):
    """Create a namespace of given dictionary

    the difference between create_namespace and python's types.SimpleNamespace
    is that the former will create name space recursively, but the later will
    create the namespace in one layer indentation. See the examples to see the
    difference.

    Parameters
    ----------
    dictionary : dict
        A dict to be converted to a namespace object

    Returns
    -------
    types.SimpleNamespace
        A combination of SimpleNamespaces that will have an multilayer
        namespace

    Examples
    --------
    >>> dictionary = {
    ...     'layer1_a': '1a',
    ...     'layer1_b': {
    ...         'layer2_a': '2a',
    ...     },
    ... }

    >>> # types.SimpleNamespace
    >>> simple = SimpleNamespace(**dictionary)
    >>> simple.layer1_a
    '1a'
    >>> simple.layer1_b.layer2_a
    AttributeError: 'dict' object has no attribute 'layer2_a'
    # because layer1_b is still a dictionary

    >>> # create_namespace
    >>> complex = create_namespace(dictionary)
    >>> complex.layer1_a
    '1a'
    >>> complex.layer1_a.layer2_a
    '2a'
    """
    space = {}
    for key, value in dictionary.items():
        if isinstance(value, dict):
            value = create_namespace(value)
        space[key] = value
    return SimpleNamespace(**space)

但我认为有更好的方法,我没有看到。我感谢任何关于此的 cmets。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 2019-08-08
    • 2013-05-17
    • 1970-01-01
    • 2012-04-17
    • 2017-01-25
    • 2011-12-18
    相关资源
    最近更新 更多