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

问题描述 投票:0回答:6

为了交互式测试我的 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'
python namespaces argparse
6个回答
213
投票

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

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
    为 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()
    实例来说,相等性测试和生成表示要快一些。

26
投票

现在建议使用 types 模块中的 SimpleNamespace。它与接受的答案做同样的事情,除了它会更快并且有更多的内置函数,例如 equals 和 repr。

from types import SimpleNamespace

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

# output
'test'

4
投票

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

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

0
投票

如果你喜欢短代码,你只需要添加一行额外的代码来定义一个空类:

class dummy:pass
obj = dummy()

其中

dummy
可以是程序中未定义的任何字符串。那么
obj
将是一个命名空间。

您还可以在一行中初始化一些命名空间成员:

class dummy:a=1;b=2
obj = dummy()

print(obj.a+' '+obj.b)

Python 的一个设计缺陷是,没有像创建元组、列表、字典等那样直接的方法来创建最基本的 Python 对象(即命名空间对象)。如果我是设计师,我会让

 a=<>
创建一个空命名空间
a


0
投票

无需创建命名空间实例即可解决问题的替代解决方案可能是 ArgumentParser 构造函数的

exit_on_error
参数。

如果设置为 false,则不应退出 REPL。

来源:https://docs.python.org/3/library/argparse.html#argumentparser-objects


-5
投票

argparse 文档 显示了您想要执行的操作的各种示例:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-a")
parser.parse_args(['-a 12'])
>>> Namespace(a=' 12')
© www.soinside.com 2019 - 2024. All rights reserved.