Làm thế nào để có được tất cả các giá trị từ lớp python enum?


140

Tôi đang sử dụng thư viện Enum4 để tạo một lớp enum như sau:

class Color(Enum):
    RED = 1
    BLUE = 2

Tôi muốn in [1, 2]như một danh sách ở đâu đó. Làm thế nào tôi có thể đạt được điều này?

Câu trả lời:


48

Bạn có thể sử dụng IntEnum :

from enum import IntEnum

class Color(IntEnum):
   RED = 1
   BLUE = 2


print(int(Color.RED))   # prints 1

Để có được danh sách các số nguyên:

enum_list = list(map(int, Color))
print(enum_list) # prints [1, 2]

Bạn sử dụng một bên thứ ba. Nhưng nó cũng nói rằng nó có intenum
Marcin

Làm cách nào để tôi in như [(1, 'ĐỎ'), (2, 'XANH')]
user1159517

Điều gì về điều này: a = [(int(v), str(v)) for v in Color]và sau đó print(a).
Marcin

34
Làm thế nào về điều này:[(color.value, color.name) for color in Color]
vlad-ardelean

2
Nhận xét của @ vlad-ardelean là tốt nhất và pythonic nhất. Rằng việc sử dụng thành ngữ của kiểu Enum, thanh lịch, và xuất sắc có thể đọc được
dusktreader

429

Bạn có thể làm như sau:

[e.value for e in Color]

1
@ user2340939 Điều đó trả về danh sách các enum, không phải danh sách các giá trị. Nếu bạn OK với điều đó, bạn cũng có thể sử dụnglist(Color)
endolith

22

Để sử dụng Enum với bất kỳ loại giá trị nào, hãy thử điều này: Được
cập nhật với một số cải tiến ... Cảm ơn @Jeff, bằng mẹo của bạn!

from enum import Enum

class Color(Enum):
    RED = 1
    GREEN = 'GREEN'
    BLUE = ('blue', '#0000ff')

    @staticmethod
    def list():
        return list(map(lambda c: c.value, Color))

print(Color.list())

Kết quả là:

[1, 'GREEN', ('blue', '#0000ff')]

6
Tôi sẽ sử dụng @ classmethod thay vì @ staticmethod
ISONecroMAn

1
@ISONecroMAn Tôi đoán @classmethodsẽ yêu cầu tạo thể hiện của Colorlớp. Đó là lý do tại sao staticmethoddường như là lựa chọn chính xác ở đây.
Leonid Dashko

@LeonidDashko hoàn toàn không. Xem câu trả lời của tôi.
blueFast

@LeonidDashko @dangoonfast là chính xác. Bạn có thể sử dụng @classmethodvà sử dụng return list(map(lambda c: c.value, cls))thay thế.
Riptyde4

18

Dựa trên câu trả lời của @Jeff, tái cấu trúc để sử dụng một classmethodđể bạn có thể sử dụng lại cùng một mã cho bất kỳ enum nào của bạn:

from enum import Enum

class ExtendedEnum(Enum):

    @classmethod
    def list(cls):
        return list(map(lambda c: c.value, cls))

class OperationType(ExtendedEnum):
    CREATE = 'CREATE'
    STATUS = 'STATUS'
    EXPAND = 'EXPAND'
    DELETE = 'DELETE'

print(OperationType.list())

Sản xuất:

['CREATE', 'STATUS', 'EXPAND', 'DELETE']

7

lớp enum.Enumlà một lớp giải quyết tất cả các nhu cầu liệt kê của bạn, vì vậy bạn chỉ cần kế thừa từ nó và thêm các trường của riêng bạn. Rồi từ đó trở đi, tất cả những gì bạn cần làm là chỉ gọi các thuộc tính của nó: name& value:

from enum import Enum

class Letter(Enum):
   A = 1
   B = 2
   C = 3

print({i.name: i.value for i in Letter})
# prints {'A': 1, 'B': 2, 'C': 3}

6

Vì vậy, Enumcó một __members__dict. Giải pháp mà @ozgur đề xuất thực sự là tốt nhất, nhưng bạn có thể làm điều này, thực hiện điều tương tự, với nhiều công việc hơn

[color.value for color_name, color in Color.__members__.items()]

Các __members__từ điển có thể có ích nếu bạn muốn chèn thứ tự động ở trong đó ... trong một số tình huống điên.

[EDIT] Rõ ràng__members__ không phải là một từ điển, mà là một proxy bản đồ. Điều đó có nghĩa là bạn không thể dễ dàng thêm các mục vào nó.

Tuy nhiên, bạn có thể làm những thứ kỳ lạ như MyEnum.__dict__['_member_map_']['new_key'] = 'new_value', và sau đó bạn có thể sử dụng khóa mới như MyEnum.new_key.... nhưng đây chỉ là một chi tiết triển khai và không nên chơi. Ma thuật đen được trả cho chi phí bảo trì rất lớn.


Chỉ cần một thanh bên: các mục có thể được thêm vào __members__? Đó sẽ là một cách thú vị để cho phép các tiện ích mở rộng từ đó tạo ra các Enumthành viên mới . ... btw, được nâng cấp để mang thuộc tính mới ( cho tôi ) vào bảng.
Tôi chấp nhận

@IAbauge: Không, điều đó không được phép. Nếu ai đó tìm ra cách thêm / bớt thành viên sau khi Enum được tạo, họ có thể sẽ phá vỡ Enum đó.
Ethan Furman

@IAb bát: Thêm thành viên mới sau khi thực tế thường không phải là một ý tưởng tốt. Nếu bạn thực sự muốn, hãy xem câu trả lời này .
Ethan Furman

1

Sử dụng _member_names_cho một kết quả dễ dàng nhanh chóng nếu nó chỉ là tên, tức là

Color._member_names_

Ngoài ra, bạn có _member_map_trả về một từ điển theo thứ tự của các yếu tố. Hàm này trả về a collections.OrderedDict, vì vậy bạn có Color._member_names_.items()Color._member_names_.values()chơi với. Ví dụ

return list(map(lambda x: x.value, Color._member_map_.values()))

sẽ trả về tất cả các giá trị hợp lệ của Màu


-1

bạn có thể sử dụng hàm iter ():

from enum import IntEnum

class Color(IntEnum):
   RED = 1
   BLUE = 2
l=[]
for i in iter(Color):
    l.append(i.value)
print(l)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.