จะรับค่าทั้งหมดจากคลาส python enum ได้อย่างไร?


155

ฉันใช้ไลบรารี Enum4 เพื่อสร้างคลาส enum ดังนี้:

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

ฉันต้องการพิมพ์[1, 2]เป็นรายการที่ไหนสักแห่ง ฉันจะบรรลุเป้าหมายนี้ได้อย่างไร?

คำตอบ:


57

คุณสามารถใช้IntEnum :

from enum import IntEnum

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


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

ในการรับรายการ ints:

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

คุณใช้บุคคลที่สาม แต่มันก็บอกว่ามี intenum
Marcin

ฉันจะพิมพ์ [(1, 'RED'), (2, 'BLUE')] ได้อย่างไร
user1159517

อะไรประมาณนี้: แล้วa = [(int(v), str(v)) for v in Color] print(a)
Marcin

42
เกี่ยวกับเรื่องนี้[(color.value, color.name) for color in Color]
vlad-ardelean

2
ความคิดเห็นของ @vlad-ardelean เป็นสิ่งที่ดีที่สุดและเป็นที่นิยมมากที่สุด นั่นเป็นการใช้สำนวนของประเภท Enum ที่สง่างามและอ่านได้อย่างเด่นชัด
Dusktreader

479

คุณสามารถทำสิ่งต่อไปนี้:

[e.value for e in Color]

1
@ user2340939 ที่ส่งคืนรายการ enums ไม่ใช่รายการค่า ถ้าคุณโอเคกับสิ่งนั้นคุณก็อาจใช้list(Color)
endolith

26

หากต้องการใช้ Enum กับค่าประเภทใด ๆ ให้ลองสิ่งนี้:
อัปเดตพร้อมการปรับปรุงบางอย่าง ... ขอบคุณ @Jeff จากคำแนะนำของคุณ!

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

ผลลัพธ์:

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

6
ฉันจะใช้ @classmethod แทน @ staticmethod
ISONecroMA ใน

1
@ISONecroMAn ฉันเดาว่า@classmethodจะต้องสร้างอินสแตนซ์ของColorคลาส นั่นเป็นเหตุผลว่าทำไมที่นี่จึงstaticmethodเป็นทางเลือกที่ถูกต้อง
Leonid Dashko

1
@LeonidDashko ไม่เลย. ดูคำตอบของฉัน
blueFast

@LeonidDashko @dangoonfast ถูกต้อง คุณสามารถใช้@classmethodและใช้return list(map(lambda c: c.value, cls))แทนได้
Riptyde4

การพยายามปรับปรุงความเร็วของสิ่งนี้มีสองบันทึก: การใช้Color.__members__.values()แทนสีในการmap()โทรจะทำให้คุณได้รับการเพิ่มขึ้น 30% ทันที operator.attrgetter('value')แล้วคุณจะได้รับความเร็วมากขึ้นอีกนิดด้วยการแทนที่แลมบ์ดาด้วย
Giacomo Lacava

21

จากคำตอบของ @Jeff refactored เพื่อใช้ a classmethodเพื่อให้คุณสามารถใช้รหัสเดิมซ้ำสำหรับ enums ของคุณ:

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

ผลิต:

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

9

คลาสenum.Enumเป็นคลาสที่ตอบสนองความต้องการการแจงนับของคุณทั้งหมดดังนั้นคุณเพียงแค่ต้องสืบทอดจากคลาสและเพิ่มฟิลด์ของคุณเอง จากนั้นสิ่งที่คุณต้องทำก็แค่เรียกมันว่าแอตทริบิวต์: 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

ดังนั้นจึงEnumมีคำ__members__สั่ง วิธีแก้ปัญหาที่ @ozgur เสนอเป็นวิธีที่ดีที่สุด แต่คุณสามารถทำได้ซึ่งทำได้เหมือนกันและทำงานได้มากขึ้น

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

__members__พจนานุกรมสามารถเข้ามามีประโยชน์ถ้าคุณต้องการที่จะใส่สิ่งแบบไดนามิกในนั้น ... ในสถานการณ์บางบ้า

[แก้ไข] เห็นได้ชัดว่า__members__ไม่ใช่พจนานุกรม แต่เป็นพร็อกซีแผนที่ ซึ่งหมายความว่าคุณไม่สามารถเพิ่มรายการได้อย่างง่ายดาย

อย่างไรก็ตามคุณสามารถทำสิ่งแปลก ๆ เช่นMyEnum.__dict__['_member_map_']['new_key'] = 'new_value'จากนั้นคุณสามารถใช้คีย์ใหม่เช่นMyEnum.new_key.... แต่นี่เป็นเพียงรายละเอียดการใช้งานเท่านั้นและไม่ควรเล่นด้วย มนต์ดำจ่ายค่าบำรุงรักษามหาศาล


เพียงแถบด้านข้าง: สามารถเพิ่มรายการได้__members__หรือไม่? เป็นวิธีที่น่าสนใจในการอนุญาตให้มีส่วนขยายจึงสร้างEnumสมาชิกใหม่ ... btw โหวตให้นำแอตทริบิวต์ใหม่ ( ให้ฉัน ) ไปที่ตาราง
IAbstract

@IAbstract: ไม่ได้รับอนุญาต หากมีใครหาวิธีเพิ่ม / ลบสมาชิกหลังจากสร้าง Enum แล้วพวกเขาอาจทำลาย Enum นั้นได้
Ethan Furman

@IAbstract: เพิ่มสมาชิกใหม่หลังจากที่ความจริงแล้วไม่ใช่ความคิดที่ดี หากคุณต้องการจริงๆลองดูคำตอบนี้
Ethan Furman

2

ใช้_member_names_เพื่อผลลัพธ์ที่ง่ายอย่างรวดเร็วหากเป็นเพียงชื่อเช่น

Color._member_names_

นอกจากนี้คุณมี_member_map_ซึ่งส่งคืนพจนานุกรมที่เรียงลำดับขององค์ประกอบ ฟังก์ชันนี้จะส่งคืน a collections.OrderedDictดังนั้นคุณจึงมีColor._member_names_.items()และColor._member_names_.values()เล่นด้วย เช่น

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

จะคืนค่าที่ถูกต้องทั้งหมดของสี


2

ใช้classmethodกับ__members__:

class RoleNames(str, Enum):
    AGENT = "agent"
    USER = "user"
    PRIMARY_USER = "primary_user"
    SUPER_USER = "super_user"
    
    @classmethod
    def list_roles(cls):
        role_names = [member.value for role, member in cls.__members__.items()]
        return role_names
role_names = RoleNames.list_roles()
print(role_names)

หรือหากคุณมีคลาส Enum หลายคลาสและต้องการแยกวิธีการคลาส:

class BaseEnum(Enum):
    @classmethod
    def list_roles(cls):
        role_names = [member.value for role, member in cls.__members__.items()]
        return role_names


class RoleNames(str, BaseEnum):    
    AGENT = "agent"
    USER = "user"
    PRIMARY_USER = "primary_user"
    SUPER_USER = "super_user"
    

class PermissionNames(str, BaseEnum):
    READ = "updated_at"
    WRITE = "sort_by"
    READ_WRITE = "sort_order"

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.