我想知道枚舉和namedtuple之間有什麼區別,以及何時應該使用一個。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
- 1. typedef和enum有什麼區別
- 2. HttpContext.Current.Application.Get([some enum])和enum之間有什麼區別?
- 3. Enum和enum之間的區別
- 4. 有什麼區別`和$(Bash中有什麼區別?
- 5. ==和===有什麼區別?
- 6. ==和===有什麼區別?
- 7. 有什麼區別? :和||
- 8. ==和===有什麼區別?
- 9. '=='和'==='有什麼區別?
- 10. `&`和`ref`有什麼區別?
- 11. 有什麼區別:。!和:r!?
- 12. | 0和~~有什麼區別?
- 13. Appender和〜有什麼區別?
- 14. xtype和別名有什麼區別?
- 15. 有什麼區別
- 16. 有什麼區別
- 17. 有什麼區別?
- 18. 有什麼區別?
- 19. 有什麼區別?
- 20. 有什麼區別
- 21. 有什麼區別?
- 22. 有什麼區別?
- 23. 有什麼區別
- 24. 有什麼區別
- 25. Microsoft.AspNet.WebApi.OData和Microsoft.Data.OData和Microsoft.AspNet.OData有什麼區別?
- 26. 是什麼namedtuple收益和其類型名稱參數之間的區別?
- 27. Viterbi CYK和Probabilistic CYK算法有什麼區別,有什麼區別嗎?
- 28. Erlang的Ports和RPC有什麼區別?
- 29. debug.write和Trace.write有什麼區別?
- 30. LocalContainerEntityManagerFactoryBean和LocalEntityManagerFactoryBean有什麼區別?
在詢問之前,應該搜索一下。看看這些話題: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