如何创建Python命名空间(argparse.parse_args值)?

sds*_*sds 43 python namespaces argparse

为了交互式地测试我的python脚本,我想创建一个Namespace对象,类似于返回的对象argparse.parse_args().显而易见的方式,

>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.parse_args()
Namespace()
>>> parser.parse_args("-a")
usage: [-h]
: error: unrecognized arguments: - a

Process Python exited abnormally with code 2
Run Code Online (Sandbox Code Playgroud)

可能导致Python repl退出(如上所述)一个愚蠢的错误.

那么,使用给定属性集创建Python命名空间的最简单方法是什么?

例如,我可以动态创建dict(dict([("a",1),("b","c")]))但我不能将其用作Namespace:

AttributeError: 'dict' object has no attribute 'a'
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 96

您可以创建一个简单的类:

class Namespace:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)
Run Code Online (Sandbox Code Playgroud)

argparse Namespace当涉及到属性时,它的工作方式与类完全相同:

>>> args = Namespace(a=1, b='c')
>>> args.a
1
>>> args.b
'c'
Run Code Online (Sandbox Code Playgroud)

或者,只需导入该类 ; 它可以从argparse模块中获得:

from argparse import Namespace

args = Namespace(a=1, b='c')
Run Code Online (Sandbox Code Playgroud)

从Python 3.3开始,还有types.SimpleNamespace一些基本上做同样的事情:

>>> from types import SimpleNamespace
>>> args = SimpleNamespace(a=1, b='c')
>>> args.a
1
>>> args.b
'c'
Run Code Online (Sandbox Code Playgroud)

这两种类型是截然不同的; SimpleNamespace主要用于sys.implementation属性和返回值time.get_clock_info().

进一步比较:

  • 两个类都支持相等测试; 对于同一类的两个实例,instance_a == instance_b如果它们具有相同值的相同属性,则为true.
  • 这两个类都有助于__repr__显示它们具有的属性.
  • Namespace()对象支持遏制测试; 'attrname' in instance如果名称空间实例具有属性namend,则为true attrname.SimpleNamespace才不是.
  • Namespace()对象具有未记录的._get_kwargs()方法,该方法返回(name, value)该实例的已排序的属性列表.你可以使用相同的课程sorted(vars(instance).items()).
  • 虽然SimpleNamespace()在C Namespace()中实现并且在Python中实现,但属性访问并不快,因为它们__dict__对属性使用相同的存储.对于SimpleNamespace()实例,平等测试和生成表示的速度要快一些.

  • 前一个简单类实际上是types.SimpleNamespace:请参阅https://docs.python.org/dev/library/types.html#types.SimpleNamespace. (4认同)

Mit*_*lls 5

现在建议从类型模块中使用SimpleNamespace。它的作用与已接受的答案相同,只是它会更快并且具有更多的内置函数,例如equals和repr。

from types import SimpleNamespace

sn = SimpleNamespace()
sn.a = 'test'
sn.a

# output
'test'
Run Code Online (Sandbox Code Playgroud)

  • argparse.Namespace还实现了__repr__和__eq__。`SimpleNamespace` *是用C实现的,但是只有相等测试和`repr()`输出会更快一些。属性访问同样快,因为它们都使用完全相同的机制来存储和查找属性。argparse.Namespace()也实现了__contains__,因此您可以在ns_instance中使用if,并且有一个未公开的`._get_kwargs()`方法;`SimpleNamespace()`都没有。 (2认同)

You*_* Hu 5

首先创建一个字典,然后使用该字典创建命名空间:

from argparse import Namespace
x = {'a': 1, 'b': 2}
ns = Namespace(**x)
print(ns.a) #output 1
Run Code Online (Sandbox Code Playgroud)