enum和namedtuple有什么区别?
作为一个比喻(虽然不完美的),则可以想到在python enum.Enum
和namedtuple
如enum
和C. struct
换句话说,enum
s为消除的值的一种方式,而namedtuple
是封装的一种方式数据按名称。这两者并非真正可互换,您可以使用enum
s作为namedtuple
中的命名值。
我觉得这个例子说明了区别。
from collections import namedtuple
from enum import Enum
class HairColor(Enum):
blonde = 1
brown = 2
black = 3
red = 4
Person = namedtuple('Person', ['name','age','hair_color'])
bert = Person('Bert', 5, HairColor.black)
您可以像访问常规对象一样访问指定的“属性”。
>>> print(bert.name)
Bert
>>> print(bert.age)
5
>>> print(bert.hair_color)
HairColor.black
>>> print(bert.hair_color.value)
3
你经常看不到namedtuple
好像是因为相同的基本概念,可以通过使用更广为人知class
声明来完成。以下定义的class
行为几乎与上面的namedtuple
定义相同。
class Person:
def __init__(self, name, age, hair_color):
self.name = name
self.age = age
self.hair_color = hair_color
然而,namedtuple
和class
对象之间的主要区别在于,一个namedtuple
的属性不能创建后进行更改。
你也可以使用'namedtuple's作为enum的值...'class People(enum.Enum):john = Person('John',21,HairColor.blonde)' – Bakuriu
的namedtuple是,使用__slots__代替__dict__一个快速结构,最终确定在初始化您提供的内容(即几乎成为只读,虽然_replace()方法存在)。
当需要很多(如数百,数千甚至数百万个)相同类型的对象或者您正在读取和/或正在写入记录时,通常会使用namedtuple。
例如,一个经常被引用的例子是一个Point命名的元组,它可能被用来处理一个带有x, y, z
组件的多边形顶点。
namedtuple在常规元组上引入的开销是最小的,如果与总是用名称(.x,.y,.z,...)而不是索引指向正确组件的好处相比, (0,1,2,...)。
阅读代码如A.x比A [0]更容易:甚至在编写代码几个月之后,其含义也很明显,对其他程序员来说也更好。
因此,一个namedtuple速度很快,可以用来有意义地识别元组的内容,最后但并非最不重要的是,可以与以前通过索引访问元组内容的代码共存。
from collections import namedtuple
Point = namedtuple('Point', 'x y z') # note the x, y, z fields
origin = Point(0, 0, 0)
A = Point(1, 1, 1)
B = Point(1, 1, 0)
C = Point(1, 0, 0)
D = Point(1, 2, 3)
for p in (origin, A, B, C, D):
print(p)
print('x:', p.x, ' y:', p.y, ' z:', p.z)
print('x:', p[0], ' y:', p[1], ' z:', p[2])
print()
从例如你打算在上面,只要一切按名称,而不是通过索引访问点的组件,进一步的变化可能会更容易地引入,由不会到改变任何索引号:
from collections import namedtuple
Point = namedtuple('Point', 'name x y z') # addition of the field 'name'
origin = Point('O', 0, 0, 0)
A = Point('A', 1, 1, 1)
B = Point('B', 1, 1, 0)
C = Point('C', 1, 0, 0)
D = Point('D', 1, 0, 1)
for p in (origin, A, B, C, D):
print(p)
print(p.name) # more readable than p[0] that is no more the x coordinate
print('x:', p.x, ' y:', p.y, ' z:', p.z) # unchanged
print('x:', p[1], ' y:', p[2], ' z:', p[3]) # changed
print()
枚举是一种将符号名称耦合到常量值并将它们分类为特定集合的方法。我们通过创建从Enum或IntEnum派生的类来定义枚举,具体取决于我们希望常量所具有的值:Enum是泛型版本,IntEnum强制实现每个常量值都是int类型的事实。例如,枚举可以很好地按名称,特定整数类型,性别来定义颜色,或者再次 - 更一般地说 - 属于特定集合的元素。
from enum import Enum, IntEnum, unique
class Color_1(Enum):
red = 'red'
green = 'green'
blue = 'blue'
class Color_2(Enum):
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
class Color_3(IntEnum):
red = 0xFF0000
green = 0xFF00
blue = 0xFF
class Gender_1(Enum):
unknown = 'U'
male = 'M'
female = 'F'
class Gender_2(Enum):
unknown = 0.3
male = 0.5
female = 0.7
class Shape(Enum): # Note the different constants types, perfectly legal
TRIANGLE = 't'
RECTANGLE = 5
SQUARE = tuple('square')
class DataType(IntEnum):
int8 = -8
int16 = -16
int32 = -32
int64 = -64
int = -2
negative = -1
positive = 1
uint = 2
uint8 = 8
uint16 = 16
uint32 = 32
uint64 = 64
在Python的发展 - 枚举元素可能会被分配一个特定的值 - 这可以是唯一的或不是,根据自己的喜好和规范。 独特的装饰器用于强制值的唯一性。默认情况下,可以将相同的常量值分配给两个或更多不同的符号名称。
class Color_4(IntEnum):
red = 1
green = 2
blue = 3
RED = 1
GREEN = 2
BLUE = 3
枚举元素可以相互比较,但对他们来说是成功的,不仅要值匹配,即使它们的类型必须相同。
例如:
Color_4.red == Color_4.RED
将返回TRUE(同一类别,相同的值),但以下几点:
Shape.SQUARE == tuple('square')
将假 - 因为比较合适的元素 - 元组( 'square') - 不是Shape类型,虽然它们都具有相同的值。
总之,枚举和namedtuples是不同的工具。
最近刚刚向Python添加了枚举(搜索PEP435)。如果记忆提供给我的权利,namedtuples可以使用很长时间,但我仍然是一个社区新手,因此我可能是错的。 HTH
在询问之前,应该搜索一下。看看这些话题:http://stackoverflow.com/questions/2970608/what-are-named-tuples-in-python和http://stackoverflow.com/questions/36932/how-can-i-represent-an -enum-in-python – Kiogara