enum --- پشتیبانی از شمارش‌ها

اضافه شده در نسخه‌ی 3.4.

کد منبع: Lib/enum.py


یک شمارش:

  • مجموعه‌ای از نام‌های نمادین (اعضا) است که به مقادیر یکتا مقید شده‌اند

  • می‌توان آن را پیمایش کرد تا اعضای کانونیکال (یعنی غیرمستعار) آن به ترتیب تعریف برگردانده شوند

  • از سینتکس call برای برگرداندن اعضا بر اساس مقدار استفاده می‌کند

  • از سینتکس اندیس برای برگرداندن اعضا بر اساس نام استفاده می‌کند

شمارش‌ها یا با استفاده از سینتکس class یا با استفاده از سینتکس فراخوانی تابع ایجاد می‌شوند:

>>> from enum import Enum

>>> # class syntax
>>> class Color(Enum):
...     RED = 1
...     GREEN = 2
...     BLUE = 3

>>> # functional syntax
>>> Color = Enum('Color', [('RED', 1), ('GREEN', 2), ('BLUE', 3)])

اگرچه شما می‌توانید از سینتکس class برای ایجاد Enumها استفاده کنید، Enumها کلاس‌های معمولی پایتون نیستند. برای جزئیات بیشتر Enumها چگونه متفاوت هستند؟ را ببینید.

توجه

نام‌گذاری

  • کلاس Color یک شمارش (یا enum) است

  • ویژگی‌های Color.RED، Color.GREEN و غیره، اعضای شمارشی (یا اعضا) هستند و از نظر عملکردی ثابت هستند.

  • اعضای enum دارای نام‌ها و مقدارها هستند (نام Color.RED برابر RED است، مقدار Color.BLUE برابر 3 است، و غیره)


محتویات ماژول

EnumType

type برای Enum و زیرکلاس‌های آن.

Enum

کلاس پایه برای ایجاد ثوابت شمارشی.

IntEnum

کلاس پایه برای ایجاد ثابت‌های شمارشی که همچنین زیرکلاس‌هایی از int هستند. (Notes)

StrEnum

کلاس پایه برای ایجاد ثابت‌های شمارشی که زیرکلاس‌هایی از str نیز هستند. (Notes)

Flag

کلاس پایه برای ایجاد ثابت‌های شمارش‌شده که می‌توان آن‌ها را با استفاده از عملیات بیتی ترکیب کرد، بدون آنکه عضویت آن‌ها در Flag از دست برود.

IntFlag

کلاس پایه برای ایجاد ثابت‌های شمارشی که می‌توان آن‌ها را با استفاده از عملگرهای بیتی ترکیب کرد، بدون از دست دادن عضویت آن‌ها در IntFlag. اعضای IntFlag همچنین زیرکلاس‌هایی از int هستند. (Notes)

ReprEnum

توسط IntEnum، StrEnum و IntFlag استفاده می‌شود تا str() نوع افزوده‌شده (mixed-in) حفظ شود.

EnumCheck

یک شمارش با مقادیر CONTINUOUS، NAMED_FLAGS و UNIQUE، برای استفاده با verify() تا اطمینان حاصل شود که محدودیت‌های مختلف توسط یک شمارش مشخص برآورده می‌شوند.

FlagBoundary

یک شمارش با مقادیر STRICT، CONFORM، EJECT و KEEP که امکان کنترل دقیق‌تر بر چگونگی رسیدگی به مقادیر نامعتبر در یک شمارش را فراهم می‌کند.

EnumDict

زیرکلاسی از dict برای استفاده هنگام زیرکلاس‌سازی از EnumType.

auto

نمونه‌ها با مقدار مناسبی برای اعضای Enum جایگزین می‌شوند. مقدار پیش‌فرض StrEnum نسخه با حروف کوچک نام عضو است، در حالی که مقدار پیش‌فرض سایر Enumها ۱ است و از آن مقدار افزایش می‌یابد.

@~enum.property

به اعضای Enum اجازه می‌دهد ویژگی‌هایی داشته باشند که با نام اعضا تداخل نمی‌کنند. ویژگی‌های value و name به همین شکل پیاده‌سازی شده‌اند.

@unique

دکوراتور کلاس Enum که تضمین می‌کند به هر مقدار تنها یک نام مقید شده باشد.

@verify

دکوراتور کلاس Enum که محدودیت‌های قابل‌انتخاب توسط کاربر روی یک شمارش را بررسی می‌کند.

@member

obj را به یک عضو تبدیل می‌کند. می‌تواند به‌عنوان دکوراتور استفاده شود.

@nonmember

obj را عضو نکنید. می‌تواند به‌عنوان دکوراتور استفاده شود.

@global_enum

str() و repr() یک شمارش (enum) را تغییر می‌دهد؛ اعضای آن به‌جای کلاس شمارش، متعلق به ماژول نمایش داده می‌شوند و اعضای شمارش به فضای نام سراسری اکسپورت می‌شوند.

show_flag_values()

فهرستی از تمام اعداد صحیح توان دو موجود در یک پرچم را برمی‌گرداند.

enum.bin()

مانند bin() توکار، با این تفاوت که مقادیر منفی به‌صورت مکمل دو نمایش داده می‌شوند و بیت پیشرو همیشه علامت را نشان می‌دهد (0 به معنای مثبت و 1 به معنای منفی است).

اضافه شده در نسخه‌ی 3.6: Flag, IntFlag, auto

اضافه شده در نسخه‌ی 3.11: StrEnum, EnumCheck, ReprEnum, FlagBoundary, property, member, nonmember, global_enum, show_flag_values

اضافه شده در نسخه‌ی 3.13: EnumDict


انواع داده

class enum.EnumType

EnumType فراکلاس برای شمارش‌های enum است. امکان زیرکلاس‌سازی EnumType وجود دارد -- برای جزئیات، زیرکلاس‌سازی EnumType را ببینید.

EnumType مسئول تنظیم متدهای صحیح __repr__()، __str__()، __format__() و __reduce__() بر روی enum نهایی، و همچنین ایجاد اعضای enum، مدیریت صحیح موارد تکراری، فراهم کردن پیمایش بر روی کلاس enum و غیره است.

اضافه شده در نسخه‌ی 3.11: پیش از 3.11، EnumType با نام EnumMeta شناخته می‌شد، که هنوز به‌عنوان یک نام مستعار در دسترس است.

__call__(cls, value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

این متد به دو روش مختلف فراخوانی می‌شود:

  • برای جست‌وجوی یک عضو موجود:

    cls:

    کلاس enum که فراخوانی می‌شود.

    مقدار:

    مقدار مورد جستجو.

  • برای استفاده از enum cls جهت ایجاد یک enum جدید (تنها در صورتی که enum موجود هیچ عضوی نداشته باشد):

    cls:

    کلاس enum که فراخوانی می‌شود.

    مقدار:

    نام Enum جدیدی که باید ایجاد شود.

    نام‌ها:

    نام‌ها/مقادیر اعضای Enum جدید.

    ماژول:

    نام ماژولی که Enum جدید در آن ایجاد می‌شود.

    نام کامل (qualname):

    مکان واقعی در ماژول که این Enum در آن یافت می‌شود.

    نوع:

    یک نوع میکس‌این برای Enum جدید.

    شروع:

    اولین مقدار عدد صحیح برای Enum (که توسط auto استفاده می‌شود).

    مرز:

    چگونگی مدیریت مقادیر خارج از محدوده حاصل از عملیات بیتی (فقط Flag).

__contains__(cls, member)

اگر عضو به cls تعلق داشته باشد، True را برمی‌گرداند:

>>> some_var = Color.RED
>>> some_var in Color
True
>>> Color.RED.value in Color
True

تغییر یافته در نسخه‌ی 3.12: پیش از Python 3.12، اگر از مقداری که عضو Enum نیست در بررسی عضویت استفاده شود، یک TypeError پرتاب می‌شود.

__dir__(cls)

['__class__', '__doc__', '__members__', '__module__'] و نام اعضای cls را برمی‌گرداند:

>>> dir(Color)
['BLUE', 'GREEN', 'RED', '__class__', '__contains__', '__doc__', '__getitem__', '__init_subclass__', '__iter__', '__len__', '__members__', '__module__', '__name__', '__qualname__']
__getitem__(cls, name)

عضو Enum در cls را که با name مطابقت دارد برمی‌گرداند، یا یک KeyError را پرتاب می‌کند:

>>> Color['BLUE']
<Color.BLUE: 3>
__iter__(cls)

هر یک از اعضای cls را به ترتیب تعریف برمی‌گرداند:

>>> list(Color)
[<Color.RED: 1>, <Color.GREEN: 2>, <Color.BLUE: 3>]
__len__(cls)

تعداد اعضای cls را برمی‌گرداند:

>>> len(Color)
3
__members__

یک نگاشت از هر نام enum به عضو آن، از جمله نام‌های مستعار، برمی‌گرداند

__reversed__(cls)

هر یک از اعضای cls را به ترتیب معکوس تعریف برمی‌گرداند:

>>> list(reversed(Color))
[<Color.BLUE: 3>, <Color.GREEN: 2>, <Color.RED: 1>]
class enum.Enum

Enum کلاس پایه برای تمام شمارش‌های enum است.

name

نام استفاده‌شده برای تعریف عضو Enum:

>>> Color.BLUE.name
'BLUE'
value

مقدار داده‌شده به عضو Enum:

>>> Color.RED.value
1

مقدار عضو را می‌توان در __new__() تنظیم کرد.

توجه

مقادیر اعضای Enum

مقادیر اعضا می‌توانند هر چیزی باشند: int، str و غیره. اگر مقدار دقیق مهم نیست، می‌توانید از نمونه‌های auto استفاده کنید و مقدار مناسبی برای شما انتخاب خواهد شد. برای جزئیات، auto را ببینید.

اگرچه می‌توان از مقادیر تغییرپذیر/هش‌ناپذیر (unhashable)، مانند dict، list یا یک dataclass تغییرپذیر استفاده کرد، اما این مقادیر در هنگام ایجاد، تأثیری درجه‌دو بر عملکرد نسبت به تعداد کل مقادیر تغییرپذیر/هش‌ناپذیر در enum خواهند داشت.

_name_

نام عضو.

_value_

مقدار عضو را می‌توان در __new__() تنظیم کرد.

_order_

دیگر استفاده نمی‌شود و برای سازگاری با نسخه‌های پیشین حفظ شده است. (صفت کلاس، در هنگام ایجاد کلاس حذف می‌شود).

می‌توان ویژگی _order_ را برای کمک به همگام نگه‌داشتن کد Python 2 / Python 3 ارائه کرد. این ویژگی با ترتیب واقعی شمارش مقایسه می‌شود و اگر این دو با هم مطابقت نداشته باشند، خطایی پرتاب می‌شود:

>>> class Color(Enum):
...     _order_ = 'RED GREEN BLUE'
...     RED = 1
...     BLUE = 3
...     GREEN = 2
...
Traceback (most recent call last):
...
TypeError: member order does not match _order_:
   ['RED', 'BLUE', 'GREEN']
   ['RED', 'GREEN', 'BLUE']

توجه

در کد Python 2، ویژگی _order_ ضروری است، زیرا ترتیب تعریف پیش از آنکه بتوان آن را ثبت کرد، از دست می‌رود.

اضافه شده در نسخه‌ی 3.6.

_ignore_

_ignore_ تنها در حین ایجاد استفاده می‌شود و پس از تکمیل ایجاد، از شمارش حذف می‌شود.

_ignore_ فهرستی از نام‌ها است که عضو نخواهند شد و نام‌هایشان نیز از شمارش کامل‌شده حذف خواهند شد. برای مشاهده یک مثال، TimePeriod را ببینید.

اضافه شده در نسخه‌ی 3.7.

__dir__(self)

بازمی‌گرداند ['__class__', '__doc__', '__module__', 'name', 'value'] و هر متد عمومی تعریف‌شده در self.__class__:

>>> from enum import Enum
>>> import datetime as dt
>>> class Weekday(Enum):
...     MONDAY = 1
...     TUESDAY = 2
...     WEDNESDAY = 3
...     THURSDAY = 4
...     FRIDAY = 5
...     SATURDAY = 6
...     SUNDAY = 7
...     @classmethod
...     def today(cls):
...         print(f'today is {cls(dt.date.today().isoweekday()).name}')
...
>>> dir(Weekday.SATURDAY)
['__class__', '__doc__', '__eq__', '__hash__', '__module__', 'name', 'today', 'value']
_generate_next_value_(name, start, count, last_values)
نام:

نام عضوی که تعریف می‌شود (مثلاً 'RED').

شروع:

مقدار شروع برای Enum؛ مقدار پیش‌فرض ۱ است.

تعداد:

تعداد اعضای تعریف‌شده در حال حاضر، بدون احتساب این عضو.

last_values:

فهرستی از مقادیر پیشین.

یک staticmethod که برای تعیین مقدار بعدی برگردانده‌شده توسط auto استفاده می‌شود.

توجه

برای کلاس‌های استاندارد Enum، مقدار بعدی انتخاب‌شده برابر با بالاترین مقدار مشاهده‌شده به‌اضافه‌ی یک است.

برای کلاس‌های Flag، مقدار انتخاب‌شده‌ی بعدی، بالاترین توان بعدی عدد ۲ خواهد بود.

می‌توان این متد را بازنویسی کرد، برای مثال:

>>> from enum import auto, Enum
>>> class PowersOfThree(Enum):
...     @staticmethod
...     def _generate_next_value_(name, start, count, last_values):
...         return 3 ** (count + 1)
...     FIRST = auto()
...     SECOND = auto()
...
>>> PowersOfThree.SECOND.value
9

اضافه شده در نسخه‌ی 3.6.

تغییر یافته در نسخه‌ی 3.13: نسخه‌های پیشین به‌جای بیشترین مقدار، از آخرین مقدار دیده‌شده استفاده می‌کردند.

__init__(self, *args, **kwds)

به‌طور پیش‌فرض، هیچ کاری انجام نمی‌دهد. اگر چندین مقدار در انتساب عضو داده شوند، آن مقادیر به آرگومان‌های جداگانه‌ای برای __init__ تبدیل می‌شوند؛ برای مثال.

>>> from enum import Enum
>>> class Weekday(Enum):
...     MONDAY = 1, 'Mon'

Weekday.__init__() به‌صورت Weekday.__init__(self, 1, 'Mon') فراخوانی می‌شود

__init_subclass__(cls, **kwds)

یک classmethod که برای پیکربندی بیشتر زیرکلاس‌های بعدی به کار می‌رود. به‌طور پیش‌فرض، کاری انجام نمی‌دهد.

_missing_(cls, value)

یک classmethod برای جست‌وجوی مقادیری که در cls یافت نمی‌شوند. به‌طور پیش‌فرض هیچ کاری انجام نمی‌دهد، اما می‌توان آن را برای پیاده‌سازی رفتار جست‌وجوی سفارشی بازنویسی کرد:

>>> from enum import auto, StrEnum
>>> class Build(StrEnum):
...     DEBUG = auto()
...     OPTIMIZED = auto()
...     @classmethod
...     def _missing_(cls, value):
...         value = value.lower()
...         for member in cls:
...             if member.value == value:
...                 return member
...         return None
...
>>> Build.DEBUG.value
'debug'
>>> Build('deBUG')
<Build.DEBUG: 'debug'>

اضافه شده در نسخه‌ی 3.6.

__new__(cls, *args, **kwds)

به‌طور پیش‌فرض، وجود ندارد. اگر مشخص شده باشد، چه در تعریف کلاس enum و چه در یک کلاس mixin (مانند int)، تمام مقادیر داده‌شده در انتساب عضو ارسال خواهند شد؛ برای مثال.

>>> from enum import Enum
>>> class MyIntEnum(int, Enum):
...     TWENTYSIX = '1a', 16

به فراخوانی int('1a', 16) و مقدار 26 برای عضو منجر می‌شود.

توجه

هنگام نوشتن __new__ سفارشی، از super().__new__ استفاده نکنید -- در عوض، __new__ مناسب را فراخوانی کنید.

__repr__(self)

رشته‌ای را برمی‌گرداند که برای فراخوانی‌های repr() استفاده می‌شود. به‌طور پیش‌فرض، نام Enum، نام عضو و مقدار را برمی‌گرداند، اما می‌توان آن را بازنویسی کرد:

>>> from enum import auto, Enum
>>> class OtherStyle(Enum):
...     ALTERNATE = auto()
...     OTHER = auto()
...     SOMETHING_ELSE = auto()
...     def __repr__(self):
...         cls_name = self.__class__.__name__
...         return f'{cls_name}.{self.name}'
...
>>> OtherStyle.ALTERNATE, str(OtherStyle.ALTERNATE), f"{OtherStyle.ALTERNATE}"
(OtherStyle.ALTERNATE, 'OtherStyle.ALTERNATE', 'OtherStyle.ALTERNATE')
__str__(self)

رشته‌ی استفاده‌شده برای فراخوانی‌های str() را بازمی‌گرداند. به‌طور پیش‌فرض، نام Enum و نام عضو را بازمی‌گرداند، اما می‌توان آن را بازنویسی کرد:

>>> from enum import auto, Enum
>>> class OtherStyle(Enum):
...     ALTERNATE = auto()
...     OTHER = auto()
...     SOMETHING_ELSE = auto()
...     def __str__(self):
...         return f'{self.name}'
...
>>> OtherStyle.ALTERNATE, str(OtherStyle.ALTERNATE), f"{OtherStyle.ALTERNATE}"
(<OtherStyle.ALTERNATE: 1>, 'ALTERNATE', 'ALTERNATE')
__format__(self)

رشته‌ای را برمی‌گرداند که برای فراخوانی‌های format() و اف‌استرینگ استفاده می‌شود. به‌طور پیش‌فرض، مقدار بازگشتی __str__() را برمی‌گرداند، اما می‌توان آن را بازنویسی کرد:

>>> from enum import auto, Enum
>>> class OtherStyle(Enum):
...     ALTERNATE = auto()
...     OTHER = auto()
...     SOMETHING_ELSE = auto()
...     def __format__(self, spec):
...         return f'{self.name}'
...
>>> OtherStyle.ALTERNATE, str(OtherStyle.ALTERNATE), f"{OtherStyle.ALTERNATE}"
(<OtherStyle.ALTERNATE: 1>, 'OtherStyle.ALTERNATE', 'ALTERNATE')

توجه

استفاده از auto همراه با Enum منجر به اعداد صحیحی با مقادیر افزایشی می‌شود که از 1 شروع می‌شوند.

تغییر یافته در نسخه‌ی 3.12: پشتیبانی از دیتاکلاس افزوده شد

_add_alias_()

یک نام جدید را به‌عنوان نام مستعار به یک عضو موجود اضافه می‌کند:

>>> Color.RED._add_alias_("ERROR")
>>> Color.ERROR
<Color.RED: 1>

اگر نام از پیش به عضو دیگری اختصاص داده شده باشد، یک NameError پرتاب می‌کند.

اضافه شده در نسخه‌ی 3.13.

_add_value_alias_()

یک مقدار جدید را به‌عنوان نام مستعار برای یک عضو موجود اضافه می‌کند:

>>> Color.RED._add_value_alias_(42)
>>> Color(42)
<Color.RED: 1>
اگر مقدار از قبل به عضو دیگری پیوند داده شده باشد، یک ValueError پرتاب می‌کند.
برای دیدن یک مثال به MultiValueEnum مراجعه کنید.

اضافه شده در نسخه‌ی 3.13.

class enum.IntEnum

IntEnum همانند Enum است، اما اعضای آن همچنین عدد صحیح هستند و می‌توانند در هر جایی که یک عدد صحیح می‌تواند استفاده شود، به کار روند. اگر هرگونه عملیات مربوط به عدد صحیح با یک عضو IntEnum انجام شود، مقدار حاصل وضعیت شمارشی خود را از دست می‌دهد.

>>> from enum import IntEnum
>>> class Number(IntEnum):
...     ONE = 1
...     TWO = 2
...     THREE = 3
...
>>> Number.THREE
<Number.THREE: 3>
>>> Number.ONE + Number.TWO
3
>>> Number.THREE + 5
8
>>> Number.THREE == 3
True

توجه

استفاده از auto با IntEnum باعث ایجاد اعداد صحیحی با مقادیر افزایشی می‌شود که از 1 شروع می‌شوند.

تغییر یافته در نسخه‌ی 3.11: __str__() اکنون int.__str__() است تا بهتر از کاربرد جایگزینی ثابت‌های موجود پشتیبانی کند. __format__() از پیش به همین دلیل int.__format__() بود.

class enum.StrEnum

StrEnum همانند Enum است، اما اعضای آن نیز رشته هستند و می‌توان از آن‌ها در بیشتر همان جاهایی استفاده کرد که از یک رشته استفاده می‌شود. نتیجه‌ی هر عملیات رشته‌ای که بر روی یک عضو StrEnum یا با آن انجام شود، بخشی از شمارش نیست.

>>> from enum import StrEnum, auto
>>> class Color(StrEnum):
...     RED = 'r'
...     GREEN = 'g'
...     BLUE = 'b'
...     UNKNOWN = auto()
...
>>> Color.RED
<Color.RED: 'r'>
>>> Color.UNKNOWN
<Color.UNKNOWN: 'unknown'>
>>> str(Color.UNKNOWN)
'unknown'

توجه

در کتابخانه استاندارد جاهایی وجود دارند که دقیقاً str را به‌جای زیرکلاسی از str بررسی می‌کنند (یعنی type(unknown) == str به‌جای isinstance(unknown, str))، و در آن مکان‌ها باید از str(MyStrEnum.MY_MEMBER) استفاده کنید.

توجه

استفاده از auto با StrEnum منجر به استفاده از نام عضو با حروف کوچک به‌عنوان مقدار می‌شود.

توجه

__str__() همان str.__str__() است تا بهتر از مورد استفاده‌ی جایگزینی ثابت‌های موجود پشتیبانی کند. __format__() نیز به همین دلیل همان str.__format__() است.

اضافه شده در نسخه‌ی 3.11.

class enum.Flag

Flag همان Enum است، اما اعضای آن از عملگرهای بیتی & (AND| (OR^ (XOR) و ~ (INVERT) پشتیبانی می‌کنند؛ نتایج این عملیات، اعضای این شمارش هستند (نام‌های مستعار اعضای آن).

__contains__(self, value)

اگر مقدار در self وجود داشته باشد، True را برمی‌گرداند:

>>> from enum import Flag, auto
>>> class Color(Flag):
...     RED = auto()
...     GREEN = auto()
...     BLUE = auto()
...
>>> purple = Color.RED | Color.BLUE
>>> white = Color.RED | Color.GREEN | Color.BLUE
>>> Color.GREEN in purple
False
>>> Color.GREEN in white
True
>>> purple in white
True
>>> white in purple
False
__iter__(self)

تمام اعضای غیرمستعار موجود را بازمی‌گرداند:

>>> list(Color.RED)
[<Color.RED: 1>]
>>> list(purple)
[<Color.RED: 1>, <Color.BLUE: 4>]

اضافه شده در نسخه‌ی 3.11.

__len__(self)

تعداد اعضای پرچم را برمی‌گرداند:

>>> len(Color.GREEN)
1
>>> len(white)
3

اضافه شده در نسخه‌ی 3.11.

__bool__(self)

اگر پرچم دارای حداقل یک عضو باشد، True و در غیر این صورت False برمی‌گرداند:

>>> bool(Color.GREEN)
True
>>> bool(white)
True
>>> black = Color(0)
>>> bool(black)
False
__or__(self, other)

مقدار دودویی پرچم جاری را که با other به‌صورت OR دودویی ترکیب شده است، برمی‌گرداند:

>>> Color.RED | Color.GREEN
<Color.RED|GREEN: 3>
__and__(self, other)

پرچم فعلی را که با other AND دودویی‌شده است برمی‌گرداند:

>>> purple & white
<Color.RED|BLUE: 5>
>>> purple & Color.GREEN
<Color: 0>
__xor__(self, other)

پرچم فعلی را که با other XOR دودویی‌شده است، برمی‌گرداند:

>>> purple ^ white
<Color.GREEN: 2>
>>> purple ^ Color.GREEN
<Color.RED|GREEN|BLUE: 7>
__invert__(self)

تمام پرچم‌های موجود در type(self) را که در self نیستند، برمی‌گرداند:

>>> ~white
<Color: 0>
>>> ~purple
<Color.GREEN: 2>
>>> ~Color.RED
<Color.GREEN|BLUE: 6>
_numeric_repr_()

تابعی که برای قالب‌بندی هر مقدار عددی بی‌نام باقی‌مانده استفاده می‌شود. پیش‌فرض، repr مقدار است؛ انتخاب‌های رایج hex() و oct() هستند.

توجه

استفاده از auto با Flag منجر به اعداد صحیحی می‌شود که توان‌های دو هستند و با 1 شروع می‌شوند.

تغییر یافته در نسخه‌ی 3.11: خروجی repr() پرچم‌های با مقدار صفر تغییر کرده است. اکنون به این صورت است:

>>> Color(0)
<Color: 0>
class enum.IntFlag

IntFlag همان Flag است، اما اعضای آن همچنین اعداد صحیح هستند و می‌توانند در هر جایی که بتوان از یک عدد صحیح استفاده کرد، به کار بروند.

>>> from enum import IntFlag, auto
>>> class Color(IntFlag):
...     RED = auto()
...     GREEN = auto()
...     BLUE = auto()
...
>>> Color.RED & 2
<Color: 0>
>>> Color.RED | 2
<Color.RED|GREEN: 3>

اگر هرگونه عملیات عدد صحیح با یک عضو IntFlag انجام شود، نتیجه یک IntFlag نخواهد بود:

>>> Color.RED + 2
3

اگر یک عملیات Flag با یک عضو IntFlag انجام شود و:

  • نتیجه یک IntFlag معتبر است: یک IntFlag بازگردانده می‌شود

  • نتیجه یک IntFlag معتبر نیست: نتیجه به تنظیم FlagBoundary بستگی دارد

خروجی repr() پرچم‌های بی‌نام با مقدار صفر تغییر کرده است. اکنون به این صورت است:

>>> Color(0)
<Color: 0>

توجه

استفاده از auto همراه با IntFlag، به اعداد صحیحی منجر می‌شود که توان‌های دو هستند و از 1 شروع می‌شوند.

تغییر یافته در نسخه‌ی 3.11: __str__() اکنون int.__str__() است تا بهتر از سناریوی استفاده‌ی جایگزینی ثابت‌های موجود پشتیبانی کند. __format__() از پیش به همین دلیل int.__format__() بود.

وارونه‌سازی یک IntFlag اکنون به‌جای یک مقدار منفی، مقدار مثبتی را برمی‌گرداند که اجتماع تمام پرچم‌هایی است که در پرچم داده‌شده وجود ندارند. این با رفتار موجود Flag مطابقت دارد.

class enum.ReprEnum

ReprEnum از repr() Enum استفاده می‌کند، اما از str()نوع داده‌ی افزوده‌شده (mixed-in) استفاده می‌کند:

برای حفظ str() / format() نوع داده‌ی افزوده‌شده (mixed-in) به‌جای استفاده از str() پیش‌فرض Enum، از ReprEnum ارث ببرید.

اضافه شده در نسخه‌ی 3.11.

class enum.EnumCheck

EnumCheck شامل گزینه‌هایی است که دکوراتور verify() برای اطمینان از برقراری محدودیت‌های مختلف از آن‌ها استفاده می‌کند؛ محدودیت‌های ناموفق به یک ValueError منجر می‌شوند.

UNIQUE

اطمینان حاصل کنید که هر مقدار تنها یک نام دارد:

>>> from enum import Enum, verify, UNIQUE
>>> @verify(UNIQUE)
... class Color(Enum):
...     RED = 1
...     GREEN = 2
...     BLUE = 3
...     CRIMSON = 1
Traceback (most recent call last):
...
ValueError: aliases found in <enum 'Color'>: CRIMSON -> RED
CONTINUOUS

اطمینان حاصل کنید که هیچ مقدار جاافتاده‌ای بین عضو با کم‌ترین مقدار و عضو با بیش‌ترین مقدار وجود ندارد:

>>> from enum import Enum, verify, CONTINUOUS
>>> @verify(CONTINUOUS)
... class Color(Enum):
...     RED = 1
...     GREEN = 2
...     BLUE = 5
Traceback (most recent call last):
...
ValueError: invalid enum 'Color': missing values 3, 4
NAMED_FLAGS

اطمینان حاصل می‌کند که هر گروه/نقاب پرچم فقط شامل پرچم‌های نام‌گذاری‌شده باشد؛ این مورد هنگامی مفید است که مقدارها به‌جای تولید شدن توسط auto() مشخص می‌شوند:

>>> from enum import Flag, verify, NAMED_FLAGS
>>> @verify(NAMED_FLAGS)
... class Color(Flag):
...     RED = 1
...     GREEN = 2
...     BLUE = 4
...     WHITE = 15
...     NEON = 31
Traceback (most recent call last):
...
ValueError: invalid Flag 'Color': aliases WHITE and NEON are missing combined values of 0x18 [use enum.show_flag_values(value) for details]

توجه

CONTINUOUS و NAMED_FLAGS برای کار با اعضای دارای مقدار عدد صحیح طراحی شده‌اند.

اضافه شده در نسخه‌ی 3.11.

class enum.FlagBoundary

FlagBoundary کنترل می‌کند که مقادیر خارج از محدوده در Flag و زیرکلاس‌های آن چگونه مدیریت شوند.

STRICT

مقدارهای خارج از محدوده باعث پرتاب ValueError می‌شوند. این حالت پیش‌فرض برای Flag است:

>>> from enum import Flag, STRICT, auto
>>> class StrictFlag(Flag, boundary=STRICT):
...     RED = auto()
...     GREEN = auto()
...     BLUE = auto()
...
>>> StrictFlag(2**2 + 2**4)
Traceback (most recent call last):
...
ValueError: <flag 'StrictFlag'> invalid value 20
    given 0b0 10100
  allowed 0b0 00111
CONFORM

در مقادیر خارج از محدوده، مقادیر نامعتبر حذف می‌شوند و یک مقدار معتبر Flag باقی می‌ماند:

>>> from enum import Flag, CONFORM, auto
>>> class ConformFlag(Flag, boundary=CONFORM):
...     RED = auto()
...     GREEN = auto()
...     BLUE = auto()
...
>>> ConformFlag(2**2 + 2**4)
<ConformFlag.BLUE: 4>
EJECT

مقدارهای خارج از محدوده، عضویت خود در Flag را از دست می‌دهند و به int بازمی‌گردند.

>>> from enum import Flag, EJECT, auto
>>> class EjectFlag(Flag, boundary=EJECT):
...     RED = auto()
...     GREEN = auto()
...     BLUE = auto()
...
>>> EjectFlag(2**2 + 2**4)
20
KEEP

مقادیر خارج از محدوده حفظ می‌شوند، و عضویت در Flag حفظ می‌شود. این پیش‌فرض برای IntFlag است:

>>> from enum import Flag, KEEP, auto
>>> class KeepFlag(Flag, boundary=KEEP):
...     RED = auto()
...     GREEN = auto()
...     BLUE = auto()
...
>>> KeepFlag(2**2 + 2**4)
<KeepFlag.BLUE|16: 20>

اضافه شده در نسخه‌ی 3.11.

class enum.EnumDict

EnumDict یک زیرکلاس از dict است که به‌عنوان فضای نام برای تعریف کلاس‌های enum استفاده می‌شود (به آماده‌سازی فضای نام کلاس مراجعه کنید). این کلاس در دسترس قرار داده شده است تا زیرکلاس‌هایی از EnumType با رفتار پیشرفته، مانند داشتن چندین مقدار به ازای هر عضو، امکان‌پذیر شوند. باید با نام کلاس enum در حال ایجاد فراخوانی شود، در غیر این صورت نام‌های خصوصی و کلاس‌های داخلی به‌درستی مدیریت نخواهند شد.

توجه داشته باشید که فقط رابط MutableMapping (__setitem__() و update()) بازنویسی شده است. ممکن است بتوان با استفاده از سایر عملیات‌های dict مانند |= این بررسی‌ها را دور زد.

member_names

فهرستی از نام‌های اعضا.

اضافه شده در نسخه‌ی 3.13.


نام‌های __dunder__ پشتیبانی‌شده

__members__ یک نگاشت مرتب فقط‌خواندنی از آیتم‌های member_name:member است. این ویژگی فقط بر روی کلاس در دسترس است.

__new__()، در صورت مشخص شدن، باید اعضای enum را ایجاد کرده و بازگرداند؛ همچنین بسیار خوب است که _value_ عضو را به‌شکل مناسبی تنظیم کنید. پس از ایجاد همه اعضا، دیگر از آن استفاده نمی‌شود.

نام‌های _sunder_ پشتیبانی‌شده

  • _name_ -- نام عضو

  • _value_ -- مقدار عضو؛ می‌تواند در __new__ تنظیم شود

  • _missing_() -- تابع جست‌وجویی که هنگام پیدا نشدن یک مقدار استفاده می‌شود؛ می‌توان آن را بازنویسی کرد

  • _ignore_ -- فهرستی از نام‌ها، چه به‌صورت یک list و چه به‌صورت یک str، که به اعضا تبدیل نخواهند شد و از کلاس نهایی حذف خواهند شد

  • _order_ -- دیگر استفاده نمی‌شود، برای سازگاری با نسخه‌های پیشین حفظ شده است (ویژگی کلاس، در هنگام ایجاد کلاس حذف می‌شود)

  • _generate_next_value_() -- برای دریافت مقدار مناسب برای یک عضو enum به کار می‌رود؛ قابل بازنویسی است

  • _add_alias_() -- یک نام جدید را به‌عنوان نام مستعار به یک عضو موجود اضافه می‌کند.

  • _add_value_alias_() -- یک مقدار جدید را به‌عنوان نام مستعار به یک عضو موجود اضافه می‌کند.

  • اگرچه نام‌های _sunder_ به‌طور کلی برای توسعه‌ی آتی کلاس Enum رزرو شده‌اند و نمی‌توان از آن‌ها استفاده کرد، برخی به‌طور صریح مجاز هستند:

    • _repr_* (برای مثال _repr_html_)، همان‌طور که در IPython's rich display استفاده می‌شود

اضافه شده در نسخه‌ی 3.6: _missing_, _order_, _generate_next_value_

اضافه شده در نسخه‌ی 3.7: _ignore_

اضافه شده در نسخه‌ی 3.13: _add_alias_، _add_value_alias_، _repr_*


ابزارهای کاربردی و دکوراتورها

class enum.auto

از auto می‌توان به‌جای یک مقدار استفاده کرد. در صورت استفاده، سازوکار Enum متد _generate_next_value_() یک Enum را فراخوانی می‌کند تا مقدار مناسبی به دست آورد. برای Enum و IntEnum، آن مقدار مناسب برابر با آخرین مقدار به‌علاوه یک خواهد بود؛ برای Flag و IntFlag، اولین توانِ ۲ که از بیشترین مقدار بزرگ‌تر باشد خواهد بود؛ برای StrEnum، نام عضو با حروف کوچک خواهد بود. هنگام ترکیب auto() با مقادیر مشخص‌شده به‌صورت دستی باید دقت کنید.

نمونه‌های auto تنها زمانی حل می‌شوند که در بالاترین سطح یک انتساب قرار داشته باشند، چه به‌تنهایی و چه به‌عنوان بخشی از یک تاپل:

  • FIRST = auto() کار خواهد کرد (auto() با 1 جایگزین می‌شود)؛

  • SECOND = auto(), -2 کار خواهد کرد (auto با 2 جایگزین می‌شود، بنابراین 2, -2 برای ایجاد عضو SECOND در enum استفاده می‌شود؛

  • THREE = [auto(), -3] کار نخواهد کرد ([<auto instance>, -3] برای ایجاد عضو enum THREE استفاده می‌شود)

تغییر یافته در نسخه‌ی 3.11.1: در نسخه‌های پیشین، auto() باید تنها مورد موجود در خط انتساب می‌بود تا به‌درستی کار کند.

می‌توان _generate_next_value_ را برای سفارشی‌سازی مقادیر استفاده‌شده توسط auto بازنویسی کرد.

توجه

در 3.13، _generate_next_value_ پیش‌فرض همیشه بالاترین مقدار عضو را با افزایش ۱ برمی‌گرداند و اگر نوع هر یک از اعضا ناسازگار باشد، شکست خواهد خورد.

@enum.property

دکوراتوری مشابه @property توکار، اما به‌طور خاص برای شمارش‌ها. این دکوراتور اجازه می‌دهد ویژگی‌های اعضا نام‌هایی مشابه نام خود اعضا داشته باشند.

توجه

پراپرتی و عضو باید در کلاس‌های جداگانه تعریف شوند؛ برای مثال، ویژگی‌های value و name در کلاس Enum تعریف شده‌اند و زیرکلاس‌های Enum می‌توانند اعضایی با نام‌های value و name تعریف کنند.

اضافه شده در نسخه‌ی 3.11.

@enum.unique

یک دکوراتور class به‌طور خاص برای شمارش‌ها. این دکوراتور __members__ یک شمارش را جستجو می‌کند و هر نام مستعاری را که بیابد، گردآوری می‌کند؛ در صورت یافتن هر نام مستعار، ValueError همراه با جزئیات پرتاب می‌شود:

>>> from enum import Enum, unique
>>> @unique
... class Mistake(Enum):
...     ONE = 1
...     TWO = 2
...     THREE = 3
...     FOUR = 3
...
Traceback (most recent call last):
...
ValueError: duplicate values found in <enum 'Mistake'>: FOUR -> THREE
@enum.verify

یک آراینده class به‌طور خاص برای شمارش‌ها. از اعضای EnumCheck برای مشخص کردن اینکه کدام محدودیت‌ها باید بر روی شمارش آراسته‌شده بررسی شوند، استفاده می‌شود.

اضافه شده در نسخه‌ی 3.11.

@enum.member

دکوراتوری برای استفاده در enumها: هدف آن به یک عضو تبدیل می‌شود.

اضافه شده در نسخه‌ی 3.11.

@enum.nonmember

دکوراتوری برای استفاده در enumها: هدف آن به یک عضو تبدیل نمی‌شود.

اضافه شده در نسخه‌ی 3.11.

@enum.global_enum

یک دکوراتور برای تغییر str() و repr() یک enum تا اعضای آن به‌عنوان متعلق به ماژول، نه کلاس آن، نشان داده شوند. این دکوراتور فقط باید زمانی استفاده شود که اعضای enum به فضای نام سراسری ماژول اکسپورت شده‌اند (برای نمونه re.RegexFlag را ببینید).

اضافه شده در نسخه‌ی 3.11.

enum.show_flag_values(value)

فهرستی از تمام اعداد صحیح توان دو موجود در یک مقدار پرچم را برمی‌گرداند.

اضافه شده در نسخه‌ی 3.11.

enum.bin(num, max_bits=None)

مانند bin() توکار، با این تفاوت که مقادیر منفی به‌صورت مکمل دو نمایش داده می‌شوند و بیت پیشرو همیشه علامت را نشان می‌دهد (0 به معنای مثبت و 1 به معنای منفی است).

>>> import enum
>>> enum.bin(10)
'0b0 1010'
>>> enum.bin(~10)   # ~10 is -11
'0b1 0101'

اضافه شده در نسخه‌ی 3.11.


یادداشت‌ها

IntEnum، StrEnum و IntFlag

این سه نوع enum به‌عنوان جایگزین‌های مستقیم (drop-in) برای مقادیر موجود مبتنی بر عدد صحیح و رشته طراحی شده‌اند؛ به همین دلیل، محدودیت‌های اضافی دارند:

  • __str__ از مقدار عضو enum استفاده می‌کند، نه از نام آن

  • __format__ نیز، از آن‌جا که از __str__ استفاده می‌کند، از مقدار عضو enum به‌جای نام آن استفاده خواهد کرد

اگر به آن محدودیت‌ها نیاز ندارید یا آن‌ها را نمی‌خواهید، می‌توانید خودتان کلاس پایه‌ی خود را با درآمیختن نوع int یا str بسازید:

>>> from enum import Enum
>>> class MyIntEnum(int, Enum):
...     pass

یا می‌توانید str() مناسب و غیره را در enum خود مجدداً انتساب دهید:

>>> from enum import Enum, IntEnum
>>> class MyIntEnum(IntEnum):
...     __str__ = Enum.__str__