为了交互式测试我的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
可能导致Python repl退出(如上所述)一个愚蠢的错误。
那么,使用一组给定属性创建Python命名空间的最简单方法是什么?
例如,我可以动态创建dict
(dict([("a",1),("b","c")])
),但我不能将其用作Namespace
:
AttributeError: 'dict' object has no attribute 'a'
答案 0 :(得分:74)
您可以创建一个简单的类:
class Namespace:
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
在属性方面,它的工作方式与argparse
Namespace
类完全相同:
>>> args = Namespace(a=1, b='c')
>>> args.a
1
>>> args.b
'c'
或者,只需导入类;它可以从argparse
模块获得:
from argparse import Namespace
args = Namespace(a=1, b='c')
从Python 3.3开始,还有types.SimpleNamespace
,基本上做同样的事情:
>>> from types import SimpleNamespace
>>> args = SimpleNamespace(a=1, b='c')
>>> args.a
1
>>> args.b
'c'
这两种类型是截然不同的; SimpleNamespace
主要用于sys.implementation
属性和time.get_clock_info()
的返回值。
进一步比较:
instance_a == instance_b
如果它们具有相同值的相同属性,则为真。__repr__
来显示他们拥有的属性。Namespace()
个对象支持包含测试;如果名称空间实例具有属性名称'attrname' in instance
,则attrname
为true。 SimpleNamespace
没有。Namespace()
个对象具有未记录的._get_kwargs()
方法,该方法返回该实例的(name, value)
属性的排序列表。您可以使用sorted(vars(instance).items())
在任一课程中获得相同的内容。SimpleNamespace()
,并且在Python中实现了Namespace()
,但属性访问并不快,因为它们对属性使用相同的__dict__
存储。对于SimpleNamespace()
实例,平等测试和生成表示的速度要快一些。答案 1 :(得分:4)
现在建议从类型模块中使用SimpleNamespace。它的作用与接受的答案相同,只是它会更快,并且具有更多的内置函数,例如equals和repr。
from types import SimpleNamespace
sn = SimpleNamespace()
sn.a = 'test'
sn.a
# output
'test'
答案 2 :(得分:-3)
argparse documentation显示了您尝试做的各种示例:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-a")
parser.parse_args(['-a 12'])
>>> Namespace(a=' 12')