Bagaimana cara mendapatkan semua nilai dari kelas python enum?

140

Saya menggunakan perpustakaan Enum4 untuk membuat kelas enum sebagai berikut:

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

Saya ingin mencetak [1, 2]sebagai daftar di suatu tempat. Bagaimana saya bisa mencapai ini?

pengguna1159517
sumber

Jawaban:

48

Anda dapat menggunakan IntEnum :

from enum import IntEnum

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


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

Untuk mendapatkan daftar int:

enum_list = list(map(int, Color))
print(enum_list) # prints [1, 2]
Marcin
sumber
Anda menggunakan pihak ketiga. Tetapi juga dikatakan memiliki intenum
Marcin
Bagaimana saya mencetak seperti [(1, 'RED'), (2, 'BLUE')]
user1159517
Bagaimana dengan ini: a = [(int(v), str(v)) for v in Color]lalu print(a).
Marcin
34
Bagaimana dengan ini:[(color.value, color.name) for color in Color]
vlad-ardelean
2
Komentar @ vlad-ardelean adalah yang terbaik dan paling pythonic. Itu penggunaan idiomatik tipe Enum, elegan, dan mudah dibaca
dusktreader
431

Anda dapat melakukan hal berikut:

[e.value for e in Color]
ozgur
sumber
1
@ user2340939 Yang mengembalikan daftar enum, bukan daftar nilai. Jika Anda setuju dengan itu, Anda sebaiknya menggunakanlist(Color)
endolith
1
Ini harus ditandai sebagai jawaban yang benar.
SKYFALL26
22

Untuk menggunakan Enum dengan segala jenis nilai, coba ini:
Diperbarui dengan beberapa peningkatan ... Terima kasih @ Jeff, berdasarkan tip Anda!

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())

Sebagai hasil:

[1, 'GREEN', ('blue', '#0000ff')]
Jeff
sumber
6
Saya akan menggunakan @classmethod alih-alih @ staticmethod
ISONecroMAn
1
@ISONecroMAn Saya kira @classmethodperlu membuat instance Colorkelas. Itu sebabnya staticmethodtampaknya pilihan yang tepat di sini.
Leonid Dashko
@LeonidDashko sama sekali tidak. Lihat jawaban saya.
blueFast
@LeonidDashko @dangoonfast benar. Anda dapat menggunakan @classmethoddan menggunakan return list(map(lambda c: c.value, cls))sebagai gantinya.
Riptyde4
18

Berdasarkan jawaban oleh @Jeff, refactored untuk menggunakan classmethodsehingga Anda dapat menggunakan kembali kode yang sama untuk semua enum Anda:

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())

Menghasilkan:

['CREATE', 'STATUS', 'EXPAND', 'DELETE']
blueFast
sumber
7

kelas enum.Enumadalah kelas yang memecahkan semua kebutuhan enumerasi Anda, jadi Anda hanya perlu mewarisi darinya, dan menambahkan bidang Anda sendiri. Kemudian sejak saat itu, yang perlu Anda lakukan hanyalah memanggil atributnya saja: 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}
Meysam Azad
sumber
6

Jadi Enumada __members__dict. Solusi yang @ozgur usulkan benar-benar yang terbaik, tetapi Anda bisa melakukan ini, yang melakukan hal yang sama, dengan lebih banyak pekerjaan

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

Itu __members__ kamus bisa berguna jika Anda ingin memasukkan barang-barang secara dinamis di dalamnya ... dalam beberapa situasi gila.

[EDIT] Rupanya__members__ bukan kamus, tetapi proxy peta. Yang berarti Anda tidak dapat dengan mudah menambahkan item ke dalamnya.

Namun Anda dapat melakukan hal-hal aneh seperti MyEnum.__dict__['_member_map_']['new_key'] = 'new_value', dan kemudian Anda dapat menggunakan kunci baru seperti MyEnum.new_key.... tapi ini hanya detail implementasi, dan tidak boleh dimainkan. Ilmu hitam dibayar dengan biaya perawatan yang sangat besar.

vlad-ardelean
sumber
Hanya bilah sisi: dapatkah item ditambahkan __members__? Ini akan menjadi cara yang menarik untuk mengizinkan ekstensi sehingga menciptakan Enumanggota baru . ... btw, dipilih untuk membawa atribut baru ( ke saya ) ke tabel.
IAbstract
@Abstract: Tidak, itu tidak diizinkan. Jika seseorang menemukan cara untuk menambah / mengurangi anggota setelah Enum dibuat, mereka mungkin akan merusak Enum itu.
Ethan Furman
@IAbstract: Tambahkan anggota baru setelah faktanya biasanya bukan ide yang baik. Jika Anda benar-benar ingin, periksa jawaban ini .
Ethan Furman
1

Gunakan _member_names_untuk hasil yang mudah dan cepat jika hanya nama, yaitu

Color._member_names_

Juga, Anda memiliki _member_map_yang mengembalikan kamus elemen. Fungsi ini mengembalikan a collections.OrderedDict, jadi Anda harus Color._member_names_.items()dan Color._member_names_.values()untuk bermain dengannya. Misalnya

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

akan mengembalikan semua nilai Color yang valid

EliuX
sumber
-1

Anda dapat menggunakan fungsi iter ():

from enum import IntEnum

class Color(IntEnum):
   RED = 1
   BLUE = 2
l=[]
for i in iter(Color):
    l.append(i.value)
print(l)
Ali Shekari
sumber