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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28345780/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 03:08:07  来源:igfitidea点击:

How do I create a Python namespace (argparse.parse_args value)?

pythonnamespacesargparse

提问by sds

To interactively test my python script, I would like to create a Namespaceobject, similar to what would be returned by argparse.parse_args(). The obvious way,

为了交互式测试我的 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

may result in Python repl exiting (as above) on a silly error.

可能会导致 Python repl 退出(如上)一个愚蠢的错误。

So, what is the easiest way to create a Python namespace with a given set of attributes?

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

E.g., I can create a dicton the fly (dict([("a",1),("b","c")])) but I cannot use it as a Namespace:

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

AttributeError: 'dict' object has no attribute 'a'

采纳答案by Martijn Pieters

You can create a simple class:

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

class Namespace:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

and it'll work the exact same way as the argparseNamespaceclass when it comes to attributes:

argparseNamespace在属性方面,它将以与类完全相同的方式工作:

>>> args = Namespace(a=1, b='c')
>>> args.a
1
>>> args.b
'c'

Alternatively, just import the class; it is available from the argparsemodule:

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

from argparse import Namespace

args = Namespace(a=1, b='c')

As of Python 3.3, there is also types.SimpleNamespace, which essentially does the same thing:

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

>>> from types import SimpleNamespace
>>> args = SimpleNamespace(a=1, b='c')
>>> args.a
1
>>> args.b
'c'

The two types are distinct; SimpleNamespaceis primarily used for the sys.implementationattribute and the return value of time.get_clock_info().

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

Further comparisons:

进一步比较:

  • Both classes support equality testing; for two instances of the same class, instance_a == instance_bis true if they have the same attributes with the same values.
  • Both classes have a helpful __repr__to show what attributes they have.
  • Namespace()objects support containment testing; 'attrname' in instanceis true if the namespace instance has an attribute namend attrname. SimpleNamespacedoes not.
  • Namespace()objects have an undocumented ._get_kwargs()method that returns a sorted list of (name, value)attributes for that instance. You can get the same for either class using sorted(vars(instance).items()).
  • While SimpleNamespace()is implemented in C and Namespace()is implemented in Python, attribute access is no faster because both use the same __dict__storage for the attributes. Equality testing and producing the representation are a little faster for SimpleNamespace()instances.
  • 两个类都支持相等测试;对于同一个类的两个实例,instance_a == instance_b如果它们具有相同的属性和相同的值,则为真。
  • 这两个类都有助于__repr__显示它们具有哪些属性。
  • Namespace()对象支持收容测试;'attrname' in instance如果命名空间实例具有属性 namend ,则为 true attrnameSimpleNamespace才不是。
  • Namespace()对象有一个未公开的._get_kwargs()方法,该方法返回(name, value)该实例的排序属性列表。您可以使用sorted(vars(instance).items()).
  • 虽然SimpleNamespace()在 CNamespace()中实现并在 Python 中实现,但属性访问并没有更快,因为两者都使用相同__dict__的属性存储。例如,相等性测试和生成表示要快SimpleNamespace()一些。

回答by bvidal

argparse documentationshow various examples of what you're trying to do:

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

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-a")
parser.parse_args(['-a 12'])
>>> Namespace(a=' 12')

回答by Mitchell Walls

It is now recommended to use SimpleNamespace from the types module. It does the same thing as the accepted answer except for it will be faster and have a few more builtins such as equals and repr.

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

from types import SimpleNamespace

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

# output
'test'