可通过属性名称或索引选项访问的结构
我对 Python 非常陌生,并试图弄清楚如何创建一个具有可通过属性名称或索引访问的值的对象。例如,os.stat() 返回 stat_result 或 pwd.getpwnam() 返回 struct_passwd 的方式。
在试图弄清楚这一点时,我只遇到过上述类型的 C 实现。 Python 中没有什么特别的内容。创建此类对象的 Python 本机方法是什么?
如果这已经被广泛报道,我深表歉意。在寻找答案的过程中,我一定错过了一些使我无法找到答案的基本概念。
I am very new to Python, and trying to figure out how to create an object that has values that are accessible either by attribute name, or by index. For example, the way os.stat() returns a stat_result or pwd.getpwnam() returns a struct_passwd.
In trying to figure it out, I've only come across C implementations of the above types. Nothing specifically in Python. What is the Python native way to create this kind of object?
I apologize if this has been widely covered already. In searching for an answer, I must be missing some fundamental concept that is excluding me from finding an answer.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Python 2.6 引入了 collections.namedtuple 来简化此操作。对于较旧的 Python 版本,您可以使用命名元组配方。
直接引用文档:
Python 2.6 introduced collections.namedtuple to make this easy. With older Python versions you can use the named tuple recipe.
Quoting directly from the docs:
您不能使用与 os.stat() 和其他结果对象相同的实现。然而,Python 2.6 有一个新的工厂函数,可以创建一个类似的数据类型,称为命名元组。命名元组是其槽也可以通过名称来寻址的元组。根据文档,命名元组不需要比常规元组更多的内存,因为它们没有每个实例的字典。工厂函数签名是:
第一个参数指定新类型的名称,第二个参数是包含字段名称的字符串(空格或逗号分隔),最后,如果 verbose 为 true,工厂函数还将打印该类生成的。
示例
假设您有一个包含用户名和密码的元组。要访问用户名,您可以在位置 0 处获取该项目,并在位置 1 处访问密码:
此代码没有任何问题,但元组不是自记录的。您必须查找并阅读有关元组中字段定位的文档。这就是命名元组可以发挥作用的地方。我们可以按如下方式重新编码前面的示例:
如果您对新创建的凭据类型的代码感兴趣,可以在创建类型时将 verbose=True 添加到参数列表中,在这种特殊情况下,我们会得到以下输出:
命名元组不仅提供按名称访问字段的功能,还包含辅助函数,例如 _make() 函数,该函数有助于从序列或可迭代对象创建 Credential 实例。例如:
namedtuple 的 python 库文档有更多信息和代码示例,因此我建议您 看一下。
You can't use the same implementation as the result object of os.stat() and others. However Python 2.6 has a new factory function that creates a similar datatype called named tuple. A named tuple is a tuple whose slots can also be addressed by name. The named tuple should not require any more memory, according to the documentation, than a regular tuple, since they don't have a per instance dictionary. The factory function signature is:
The first argument specifies the name of the new type, the second argument is a string (space or comma separated) containing the field names and, finally, if verbose is true, the factory function will also print the class generated.
Example
Suppose you have a tuple containing a username and password. To access the username you get the item at position zero and the password is accessed at position one:
There's nothing wrong with this code but the tuple isn't self-documenting. You have to find and read the documentation about the positioning of the fields in the tuple. This is where named tuple can come to the rescue. We can recode the previous example as follows:
If you are interested of what the code looks like for the newly created Credential-type you can add verbose=True to the argument list when creating the type, in this particular case we get the following output:
The named tuple doesn't only provide access to fields by name but also contains helper functions such as the _make() function which helps creating an Credential instance from a sequence or iterable. For example:
The python library documentation for namedtuple has more information and code examples, so I suggest that you take a peek.
我不确定您对此有何困难。
通过索引访问的集合实现了
__getitem__
。通过名称访问的集合实现了
__getattr__
(或__getattribute__
)。您可以毫不费力地实现两者。或者,您可以使用
namedtuple
。为了让生活更简单,您可以扩展
tuple
类,这样您就不必实现自己的__getitem__
。或者,您可以定义一个也具有__getitem__
的普通类,这样您就不必弄乱__getattr__
。例如
I'm not sure what you're finding hard about this.
A collection accessible by index implements
__getitem__
.A collection accessible by names implements
__getattr__
(or__getattribute__
).You can implement both without any trouble at all. Or, you can use
namedtuple
.To make life simpler, you could extend the
tuple
class so you don't have to implement your own__getitem__
. Or you can define an ordinary class that also has__getitem__
so you didn't have to mess with__getattr__
.For example