ฉันใช้ไลบรารี Enum4 เพื่อสร้างคลาส enum ดังนี้:
class Color(Enum):
RED = 1
BLUE = 2
ฉันต้องการพิมพ์[1, 2]
เป็นรายการที่ไหนสักแห่ง ฉันจะบรรลุเป้าหมายนี้ได้อย่างไร?
ฉันใช้ไลบรารี Enum4 เพื่อสร้างคลาส enum ดังนี้:
class Color(Enum):
RED = 1
BLUE = 2
ฉันต้องการพิมพ์[1, 2]
เป็นรายการที่ไหนสักแห่ง ฉันจะบรรลุเป้าหมายนี้ได้อย่างไร?
คำตอบ:
คุณสามารถใช้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]
a = [(int(v), str(v)) for v in Color]
print(a)
[(color.value, color.name) for color in Color]
คุณสามารถทำสิ่งต่อไปนี้:
[e.value for e in Color]
list(Color)
หากต้องการใช้ 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')]
@classmethod
จะต้องสร้างอินสแตนซ์ของColor
คลาส นั่นเป็นเหตุผลว่าทำไมที่นี่จึงstaticmethod
เป็นทางเลือกที่ถูกต้อง
@classmethod
และใช้return list(map(lambda c: c.value, cls))
แทนได้
Color.__members__.values()
แทนสีในการmap()
โทรจะทำให้คุณได้รับการเพิ่มขึ้น 30% ทันที operator.attrgetter('value')
แล้วคุณจะได้รับความเร็วมากขึ้นอีกนิดด้วยการแทนที่แลมบ์ดาด้วย
จากคำตอบของ @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']
คลาส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}
ดังนั้นจึง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 โหวตให้นำแอตทริบิวต์ใหม่ ( ให้ฉัน ) ไปที่ตาราง
ใช้_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()))
จะคืนค่าที่ถูกต้องทั้งหมดของสี
ใช้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"