แนวปฏิบัติทั่วไปสำหรับ enum ใน Python คืออะไร [ทำซ้ำ]

รายการซ้ำที่เป็นไปได้:
ฉันจะทำอย่างไร เป็นตัวแทนของ 'enum' ใน Python?

แนวปฏิบัติทั่วไปสำหรับ enum ใน Python คืออะไร เช่น. พวกมันถูกจำลองแบบใน Python อย่างไร?

public enum Materials
{
    Shaded,
    Shiny,
    Transparent,
    Matte
}

person Joan Venge    schedule 31.03.2009    source แหล่งที่มา
comment
ขณะนี้มีประเภท Enum มาตรฐานใน Python 3.4 อ่านโพสต์นี้: stackoverflow.com/questions/ 16653129/   -  person Javier    schedule 01.04.2014
comment
นี่คือ PEP สำหรับประเภท enum ที่ขณะนี้อยู่ใน Python: python.org/dev /peps/pep-0435   -  person shuttle87    schedule 27.07.2015
comment
คำถามปิดมีคำตอบที่ดีที่สุด :)   -  person Apollys supports Monica    schedule 07.12.2019


คำตอบ (4)


ฉันเคยเห็นรูปแบบนี้หลายครั้ง:

>>> class Enumeration(object):
        def __init__(self, names):  # or *names, with no .split()
            for number, name in enumerate(names.split()):
                setattr(self, name, number)

>>> foo = Enumeration("bar baz quux")
>>> foo.quux
2

คุณยังสามารถใช้สมาชิกชั้นเรียนได้ แต่คุณจะต้องระบุหมายเลขของคุณเอง:

>>> class Foo(object):
        bar  = 0
        baz  = 1
        quux = 2

>>> Foo.quux
2

หากคุณกำลังมองหาบางสิ่งที่แข็งแกร่งกว่านี้ (ค่ากระจัดกระจาย ข้อยกเว้นเฉพาะ enum ฯลฯ) ลองสิ่งนี้ สูตร.

person Ben Blank    schedule 31.03.2009

ฉันไม่รู้ว่าทำไม Enums ถึงไม่รองรับ Python โดยกำเนิด วิธีที่ดีที่สุดที่ฉันพบในการเลียนแบบคือการแทนที่ _ str _ และ _ eq _ เพื่อให้คุณสามารถเปรียบเทียบได้และเมื่อคุณใช้ print() คุณจะได้รับสตริงแทนที่จะเป็นค่าตัวเลข

class enumSeason():
    Spring = 0
    Summer = 1
    Fall = 2
    Winter = 3
    def __init__(self, Type):
        self.value = Type
    def __str__(self):
        if self.value == enumSeason.Spring:
            return 'Spring'
        if self.value == enumSeason.Summer:
            return 'Summer'
        if self.value == enumSeason.Fall:
            return 'Fall'
        if self.value == enumSeason.Winter:
            return 'Winter'
    def __eq__(self,y):
       return self.value==y.value

การใช้งาน:

>>> s = enumSeason(enumSeason.Spring)

>>> print(s)

Spring
person Spell    schedule 31.03.2009
comment
PEP354 มีการแจ้งเตือนการปฏิเสธ ดู python.org/dev/peps/pep-0354/#rejection -แจ้งให้ทราบ - person Fred Larson; 01.04.2009
comment
มันจะเร็วกว่าถ้ามีพจนานุกรมคลาส {Spring: 0, Summer:1, ...} และใช้ init เพื่อวนซ้ำรายการต่างๆ และตั้งค่าแอตทริบิวต์ เพราะงั้น str สามารถดูค่าได้แทนที่จะเขียนโค้ดด้วยมือในทุกกรณี - person Charles J. Daniels; 29.03.2015
comment
ดูสิ่งนี้: python.org/dev/peps/pep-0435 - person shuttle87; 27.07.2015

คุณอาจใช้โครงสร้างการสืบทอดได้ แม้ว่ายิ่งฉันเล่นกับสิ่งนี้มากเท่าไหร่ฉันก็รู้สึกสกปรกมากขึ้นเท่านั้น

class AnimalEnum:
  @classmethod
  def verify(cls, other):
    return issubclass(other.__class__, cls)


class Dog(AnimalEnum):
  pass

def do_something(thing_that_should_be_an_enum):
  if not AnimalEnum.verify(thing_that_should_be_an_enum):
    raise OhGodWhy
person Trey Stout    schedule 31.03.2009

person    schedule
comment
ฉันไม่เคยเห็นสิ่งนั้นมาก่อน สิ่งดีๆ - person Ben Blank; 01.04.2009
comment
ปัญหาเดียวคือฉันต้องให้รายการแรกเป็น 1 เป็นไปได้ไหมที่จะทำกับวิธีการของคุณ? - person Joan Venge; 01.04.2009
comment
จากวิธีการทั้งหมดที่ฉันเคยเห็น นี่อาจเป็นวิธีโปรดของฉัน สง่างามมาก! - person goldenratio; 01.04.2009
comment
@โจน คุณทำได้ _unused, Shaded, Shiny, Transparent, Matte = range(5) - person zekel; 09.12.2010
comment
ค่อนข้างช้า แต่คุณยังสามารถทำ Shaded, Shiny, Transparent, Matte = range(1, 5) ได้ หากคุณไม่ชอบให้ _unused อยู่ที่นั่น - person Davy8; 30.01.2011
comment
คุณไม่จำเป็นต้องใช้ range โดยกำหนดค่าตัวแปรคลาสแต่ละตัวแยกกัน - person bret; 14.06.2012
comment
น่าเสียดายที่วิธีการสร้างแจงนับนี้ไม่สมบูรณ์ เนื่องจากแจงนับไม่สามารถวนซ้ำได้ และแต่ละค่าก็ไม่ใช่ประเภทที่ไม่ซ้ำกัน (เช่น แค่ int) - person Gewthen; 10.06.2015
comment
@Gewthen ในหลายภาษา enums เป็นเพียง int คาดหวังไว้ไม่มากก็น้อยใช่ไหม? หากจำเป็น คุณสามารถใช้ ตัววนซ้ำ ที่เหมาะสมได้ - person Mads Y; 02.09.2015
comment
@MadsY ในภาษาอื่น ๆ พวกเขาเป็นเพียงวากยสัมพันธ์น้ำตาลในขณะที่ภาษาอื่น ๆ (เช่น Python3) พวกเขาไม่ใช่ โดยทั่วไปการมีประเภทที่รัดกุมสำหรับค่านิยมของคุณมักจะดีกว่าในภาษาประเภทที่เคร่งครัด เนื่องจากจะใช้ภาษามากกว่า หากเป็นเพียงตัวเลข ควรจำไว้มากกว่าเมื่อทำการดีบั๊กหรือดูบันทึก ฉันอยากเห็น Materials.shinny ในบันทึกมากกว่า 1 เพราะ 1 บอกฉันน้อยกว่า Materials.shinny มาก - person Gewthen; 17.10.2015
comment
ควรอัปเดตเพื่อเพิ่มว่า enums อยู่ใน Python ตั้งแต่ 3.4 - person SudoKid; 04.01.2017