为了交互式测试我的 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'
您可以创建一个简单的类:
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')
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
为 true。__repr__
来显示它们具有哪些属性。Namespace()
对象支持遏制测试;如果命名空间实例具有属性 namend 'attrname' in instance
,则 attrname
为 true。 SimpleNamespace
没有。Namespace()
对象有一个未记录的 ._get_kwargs()
方法,该方法返回该实例的 (name, value)
属性的排序列表。您可以使用 sorted(vars(instance).items())
为任一类别获得相同的结果。SimpleNamespace()
是用 C 实现的,Namespace()
是用 Python 实现的,但属性访问速度并没有更快,因为两者都使用相同的 __dict__
存储属性。对于 SimpleNamespace()
实例来说,相等性测试和生成表示要快一些。现在建议使用 types 模块中的 SimpleNamespace。它与接受的答案做同样的事情,除了它会更快并且有更多的内置函数,例如 equals 和 repr。
from types import SimpleNamespace
sn = SimpleNamespace()
sn.a = 'test'
sn.a
# output
'test'
首先创建一个字典,然后使用该字典创建命名空间:
from argparse import Namespace
x = {'a': 1, 'b': 2}
ns = Namespace(**x)
print(ns.a) #output 1
如果你喜欢短代码,你只需要添加一行额外的代码来定义一个空类:
class dummy:pass
obj = dummy()
其中
dummy
可以是程序中未定义的任何字符串。那么 obj
将是一个命名空间。
您还可以在一行中初始化一些命名空间成员:
class dummy:a=1;b=2
obj = dummy()
print(obj.a+' '+obj.b)
Python 的一个设计缺陷是,没有像创建元组、列表、字典等那样直接的方法来创建最基本的 Python 对象(即命名空间对象)。如果我是设计师,我会让
a=<>
创建一个空命名空间 a
。
无需创建命名空间实例即可解决问题的替代解决方案可能是 ArgumentParser 构造函数的
exit_on_error
参数。
如果设置为 false,则不应退出 REPL。
来源:https://docs.python.org/3/library/argparse.html#argumentparser-objects
argparse 文档 显示了您想要执行的操作的各种示例:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-a")
parser.parse_args(['-a 12'])
>>> Namespace(a=' 12')