Tôi muốn biết sự khác nhau giữa enum và namedtuple là gì và khi nào nên sử dụng cái kia.Sự khác nhau giữa enum và namedtuple là gì?
Trả lời
Là một loại suy (mặc dù một là liều thuốc vạn), bạn có thể nghĩ enum.Enum
và namedtuple
trong python như enum
và struct
trong C. Nói cách khác, enum
s là một cách để các giá trị răng cưa, trong khi namedtuple
là một cách để đóng gói dữ liệu theo tên. Cả hai không thực sự hoán đổi cho nhau và bạn có thể sử dụng enum
s làm giá trị được đặt tên trong một namedtuple
.
Tôi nghĩ ví dụ này minh họa sự khác biệt.
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)
Bạn có thể truy cập vào tên là "thuộc tính" của con người giống như cách bạn sẽ là một đối tượng thường xuyên.
>>> print(bert.name)
Bert
>>> print(bert.age)
5
>>> print(bert.hair_color)
HairColor.black
>>> print(bert.hair_color.value)
3
Bạn thường không thấy namedtuple
s như thế này bởi vì các khái niệm cơ bản tương tự có thể được thực hiện bằng cách sử dụng biết đến rộng rãi hơn class
khai. Định nghĩa class
bên dưới hoạt động gần như giống hệt với định nghĩa namedtuple
ở trên.
class Person:
def __init__(self, name, age, hair_color):
self.name = name
self.age = age
self.hair_color = hair_color
Tuy nhiên, một sự khác biệt lớn giữa một namedtuple
và một đối tượng class
là các thuộc tính của một namedtuple
không thể thay đổi sau khi tạo nó.
Bạn cũng có thể sử dụng 'namedtuple' làm giá trị cho một enum ...' class People (enum.Enum): john = Person ('John', 21, HairColor.blonde) ' – Bakuriu
Các namedtuple là một cấu trúc nhanh rằng, sử dụng __slots__ thay vì __dict__, để hoàn tất nội dung mà bạn cung cấp lúc khởi tạo (mà thực tế trở nên chỉ đọc, mặc dù một phương pháp _replace() tồn tại).
Tên thường được sử dụng khi bạn cần nhiều đối tượng (như hàng trăm, hàng nghìn và thậm chí hàng triệu) cùng loại hoặc bạn đang đọc và/hoặc ghi một bản ghi.
Ví dụ, một ví dụ thường được trích dẫn là một điểm têntuple có thể được sử dụng để làm việc với một đỉnh đa giác với các thành phần x, y, z
của nó.
Chi phí được giới thiệu bởi một bộ tên trên một bộ thông thường là tối thiểu nếu so sánh với lợi ích của việc luôn trỏ đến đúng thành phần theo tên (.x, .y, .z, ...) thay vì theo chỉ mục (0, 1, 2, ...).
Đọc mã như A.x dễ hơn A [0]: nghĩa là hiển nhiên, thậm chí vài tháng sau khi bạn đã viết mã và, tốt hơn, cho các lập trình viên khác.
Do đó, tên tệp nhanh, có thể được sử dụng để xác định có ý nghĩa nội dung của bộ và, nhưng cuối cùng nhưng không kém phần quan trọng, có thể cùng tồn tại với mã cũ truy cập vào nội dung theo chỉ mục.
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()
Đi vào từ ví dụ trên, ngay sau khi tất cả mọi thứ đang truy cập các thành phần điểm bằng tên thay vì theo chỉ số, thay đổi hơn nữa có thể được dễ dàng hơn được giới thiệu, bằng cách không đi sâu vào việc thay đổi bất kỳ số chỉ số:
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()
An liệt kê là cách để ghép đôi các tên biểu tượng thành các giá trị không đổi và phân loại chúng thành một tập hợp cụ thể. Chúng ta định nghĩa một kiểu liệt kê bằng cách tạo một lớp bắt nguồn từ Enum hoặc IntEnum, tùy thuộc vào các giá trị mà chúng ta muốn hằng số của chúng ta có: Enum là phiên bản chung, IntEnum thực thi thực tế là mọi giá trị không đổi sẽ là kiểu int.
Ví dụ, enums là tốt để xác định màu sắc theo tên, loại số nguyên cụ thể, giới tính, hoặc, một lần nữa, - nói chung hơn - yếu tố thuộc về một tập hợp cụ thể.
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
Phát triển pythonic - các phần tử liệt kê có thể có giá trị cụ thể được chỉ định - có thể là duy nhất hay không, tùy theo sở thích và đặc điểm của bạn. Trình trang trí độc đáo được sử dụng để thực thi các giá trị độc đáo. Theo mặc định, có thể chỉ định cùng một giá trị không đổi cho hai hoặc nhiều tên biểu tượng khác nhau.
class Color_4(IntEnum):
red = 1
green = 2
blue = 3
RED = 1
GREEN = 2
BLUE = 3
Enumerations yếu tố có thể được so sánh với nhau, nhưng đối với họ để thành công, không chỉ phải trận đấu có giá trị, thậm chí loại của họ phải giống nhau.
Ví dụ:
Color_4.red == Color_4.RED
sẽ trở lại Đúng (cùng lớp, cùng một giá trị), nhưng điều sau đây:
Shape.SQUARE == tuple('square')
sẽ False - bởi vì các yếu tố bên phải của sự so sánh - tuple ('square') - không thuộc loại Shape, mặc dù cả hai đều có cùng giá trị.
Để kết luận, enums và namedtuples là các công cụ khác nhau.
Các số đếm đã được thêm gần đây vào Python (tìm kiếm PEP435). Nếu bộ nhớ phục vụ cho tôi đúng, tên gọi đã có sẵn trong một thời gian dài, nhưng tôi vẫn là một newbie cộng đồng, do đó tôi có thể sai. HTH
Và ngược lại để enums? – Billy
@Billy xin lỗi, nhưng bạn đã đến đây trong khi tôi đang viết phần thứ hai tôi vừa thêm vào lúc này. –
Từ thử nghiệm trên với 'IntEnum' tôi đã nhận thấy rằng so sánh sau đây' Color_4.red == 1' kết quả trong 'True'. Tuy nhiên, khi thực hiện '1 trong Color_4', kết quả là' False' (chỉ khi thực hiện 'Color_4.red in Color_4' sẽ dẫn đến' True') – Marc
- 1. Sự khác nhau giữa `Enum.name()` và `Enum.toString()` là gì?
- 2. Sự khác nhau giữa WPF và WinForms là gì?
- 3. Sự khác nhau giữa JavaScript và Java là gì?
- 4. Sự khác nhau giữa ODBC và OleDB là gì?
- 5. Sự khác nhau giữa SGML và XML là gì?
- 6. Sự khác nhau giữa DefaultSelenium và RemoteWebDriver là gì?
- 7. Sự khác nhau giữa RMI và Corba là gì?
- 8. Sự khác nhau giữa scgi và wsgi là gì?
- 9. Sự khác nhau giữa wsHttpBinding và ws2007HttpBinding là gì?
- 10. Sự khác nhau giữa Pingback và Trackback là gì?
- 11. Trong Python, sự khác nhau giữa ".append()" và "+ = []" là gì?
- 12. Sự khác nhau giữa AxInterop và Interop là gì?
- 13. Sự khác nhau giữa CellClick và CellMouseClick là gì?
- 14. Sự khác nhau giữa .bashrc, .bash_profile và .environment là gì?
- 15. Sự khác nhau giữa JSP và Facelets là gì?
- 16. Sự khác nhau giữa hg quên và hg là gì?
- 17. Sự khác nhau giữa GDI và GDI + là gì?
- 18. Sự khác nhau giữa đá quý và plugin là gì?
- 19. Sự khác nhau giữa metaClass.methods và metaClass.metaMethods là gì?
- 20. Sự khác nhau giữa kEND và $ end là gì?
- 21. Sự khác nhau giữa java và jsp là gì?
- 22. Sự khác nhau giữa Application.Run() và Form.ShowDialog() là gì?
- 23. Sự khác nhau giữa -0 và 0 là gì?
- 24. Sự khác nhau giữa HTTP 1.0 và 1.1 là gì?
- 25. Sự khác nhau giữa java.lang.Math và java.lang.StrictMath là gì?
- 26. Sự khác nhau giữa " " và "" là gì?
- 27. Sự khác nhau giữa Spring BeanFactoryAware và ApplicationContextAware là gì?
- 28. sự khác nhau giữa SCRIPT_FILENAME và SCRIPT_NAME là gì?
- 29. Sự khác nhau giữa JSP và JSTL là gì?
- 30. Sự khác nhau giữa JSF và Facelets là gì?
Op nên tìm kiếm một chút trước khi yêu cầu. Xem các chủ đề này: http://stackoverflow.com/questions/2970608/what-are-named-tuples-in-python và http://stackoverflow.com/questions/36932/how-can-i-represent-an -enum-in-python – Kiogara