我创建一个命名元组,如下所示:
1 2 3
| from collections import namedtuple
spam = namedtuple('eggs', 'x, y, z')
ham = spam(1,2,3) |
然后我就可以用。
1 2 3 4
| >>> ham.x
1
>>> ham.z
3 |
在翻译,
1 2
| >>> ham
eggs(x=1, y=2, z=3) |
但如果我只想要"鸡蛋"呢?我唯一能想到的就是
1 2
| >>> ham.__repr__.split('(')[0]
'eggs' |
但这看起来有点乱。有更干净的方法吗?
如果不使用私有方法就不能访问命名元组,那么为什么命名元组有这个"eggs"方面呢?
- 我想你的意思是spam = namedtuple('eggs', 'x, y, z')。
- 在Python中获取实例的类名的可能副本
- 这个问题的答案是instance. _class__。__name__虽然……
- 我不确定我是否理解反对票。你的意思是如果我读得足够多,我就能得到答案了吗?
- 我没有投反对票,我只是注意到这个问题本质上和给定的链接是一样的——一个重复的链接。
你可以得到类的__name__属性:
1 2
| >>> type(ham).__name__
'eggs' |
(这里使用type()内置函数获取类)。
- 这更好,但仍然使用私有方法。如果"eggs"不是ham对象的属性,那么为什么还要使用它呢?
- @aaren它不是一个私有方法——双下划线显示了方法的两边——或者,在本例中,属性对于Python的工作方式是特殊的。给ham对象命名没有意义,因为它不是ham对象的一部分。这是课程的一部分。类范围内的任何内容都存储在类中,这是有意义的。类的名称是必需的——因为您没有使用class语句,所以必须显式地将名称赋予python。
- @aaren它不是ham对象的属性,而是其类的属性(而该类又是对象的属性)。还要注意,它们既不是私有的,也不是方法——它们都是公共属性,尽管使用双下划线来表示魔力,并避免与用户定义的名称发生冲突。
- @Lattyware谢谢你帮我整理。
- @delnan有用,谢谢
关于namedtuple属性的主题:
1 2
| >>> ham._fields
('x', 'y', 'z') |
有时候知道这些有用吗
1 2
| >>> ham.__class__.__name__
'eggs' |
- 1。不要直接访问__class__属性,这是不好的做法。type()内建在那里是有原因的。
- @Lattyware—使用__name__访问名称并不比使用它更糟糕。每个值都是一个对象,因此有一个类(也称为其类型)。它存储为object.……class__。"
- 这是不同的,没有内置函数来获取名称。你不会做x.__len__()你会做len(x)。为什么这里会奇怪呢?
- 我不会说这是坏习惯,但我认为它很丑,而且我更喜欢type。至于__name__,没有等效的内建函数,所以它并不完全相同。(顺便提一句,在带有旧式类的Python 2中,这两个类是不同的,但是去死旧式类吧,它们需要消亡。)
- @Lattyware——因为它也适用于旧式类,所以这个问题可能与namedtuple无关,但是obj.__class__更便于移植。
- 这是避免像瘟疫一样的旧式类的另一个好理由。如果你关心他们,那你就做错了,需要加快速度。如果你因为一些不能丢弃的POS机还在而不得不关心它们,我为你感到非常抱歉。但幸运的是,所有正常的类都是新样式的,所以除非您必须大量处理遗留代码,否则没有理由关心与旧样式类的兼容性。您不会因为property不适用于旧式类而避免它,是吗?
- 这不是退缩的好理由。许多东西都不能与旧式类一起工作,但是我们也不会因此而避免使用它们。如果您正在编写新代码,请使用new-style类并将type()用于它的工作。就像你自己说的——namedtuple肯定是新型的,所以它更有意义。
- 我并不是说type()有什么问题,但是我不同意__class__是不好的实践,它在Python文档的不同地方都使用(以及您链接的重复问题的前两个答案)。
- 坏习惯可能是一个强有力的术语,但我肯定会说丑陋。在Python文档中有很多宿醉的时候,它可能更适合使用__class__——我没有在副本中对这些答案进行投票。
基于python的doc, namedtuple提供了一个名为"eggs"的新元组子类
本质上,你需要类名
type(ham).__name__将给您类名