الفرق بين المراجعتين ل"Python/enum"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
سطر 242: سطر 242:
  
 
* تصبح جميع الخاصيات الأخرى المعرّفة ضمن enumeration عناصر له؛ باستثناء التوابع الخاصة (‎<code>__str__()، __add__()‎</code>، وغيرها) والواصفات (descriptors) (التوابع واصفات أيضًا).
 
* تصبح جميع الخاصيات الأخرى المعرّفة ضمن enumeration عناصر له؛ باستثناء التوابع الخاصة (‎<code>__str__()، __add__()‎</code>، وغيرها) والواصفات (descriptors) (التوابع واصفات أيضًا).
 +
 +
== التفريع المقيد لأصناف enum ==
 +
تسمح اللغة فقط بإنشاء أصناف فرعية للـ enumeration التي لا تعرّف أي عناصر، ولهذا تعدّ الشيفرة التالية خاطئة:<syntaxhighlight lang="python3">
 +
>>> class MoreColor(Color):
 +
...    PINK = 17
 +
...
 +
Traceback (most recent call last):
 +
...
 +
TypeError: Cannot extend enumerations
 +
</syntaxhighlight>أما الشيفرة التالية فصحيحة:<syntaxhighlight lang="python3">
 +
>>> class Foo(Enum):
 +
...    def some_behavior(self):
 +
...        pass
 +
...
 +
>>> class Bar(Foo):
 +
...    HAPPY = 1
 +
...    SAD = 2
 +
</syntaxhighlight>يؤدي السماح بإنشاء أصناف فرعية للصنف enum الذي يمتلك عددًا من العناصر إلى مخالفة بعض الثوابت المهمّة في الأنواع ونسخ الأصناف، ولكن من جانب آخر من المعقول أن يُسمح بمشاركة بعض الأمور المشتركة بين مجموعة من الـ enumeration.
 +
 +
(راجع <code>OrderedEnum</code> للاطلاع على الأمثلة).
 +
 +
== عملية Pickling ==
 +
يمكن إجراء عمليتي <code>pickling</code> و <code>unpickling</code> على enumerations:<syntaxhighlight lang="python3">
 +
>>> from test.test_enum import Fruit
 +
>>> from pickle import dumps, loads
 +
>>> Fruit.TOMATO is loads(dumps(Fruit.TOMATO))
 +
True
 +
</syntaxhighlight>وتنطبق هنا جميع القيود المعروفة لعملية pickling: حيث يجب تعريف الـ enums في المستوى الأعلى من الوحدة؛ وذلك لأنّ عملية unpickling تتطلب كون هذه الـ enums قابلة للاستيراد من تلك الوحدة.
 +
 +
'''ملاحظة:''' من الممكن بالاعتماد على الإصدار الرابع من بروتوكول عملية pickling إجراء هذه العملية على enums متداخلة في أصناف أخرى.
 +
 +
من الممكن تعديل طريقة إجراء عمليتي pickling و unpickling على عناصر الصنف Enum وذلك بتعريف التابع <code>‎__reduce_ex__()</code>‎ في صنف enumeration.
 +
 +
== الواجهة البرمجية الوظيفية Functional API ==
 +
الصنف Enum قابل للاستدعاء، ويقدّم الواجهة البرمجية الوظيفية التالية:<syntaxhighlight lang="python3">
 +
>>> Animal = Enum('Animal', 'ANT BEE CAT DOG')
 +
>>> Animal
 +
<enum 'Animal'>
 +
>>> Animal.ANT
 +
<Animal.ANT: 1>
 +
>>> Animal.ANT.value
 +
1
 +
>>> list(Animal)
 +
[<Animal.ANT: 1>, <Animal.BEE: 2>, <Animal.CAT: 3>, <Animal.DOG: 4>]
 +
</syntaxhighlight>هذه الواجهة البرمجية مشابهة [[Python/tuples|للصفوف المسمّاة]]، ويكون المعامل الأول في عملية استدعاء الصنف Enum هو اسم enumeration.
 +
 +
أما المعامل الثاني <code>source</code> فهو مصدر  أسماء عناصر enumeration. يمكن لهذا المعامل أن يكون [[Python/str|سلسلة نصية]] تتضمن أسماء مفصولة عن بعضها البعض بمسافات بيضاء، أو تسلسل من الأسماء، أو تسلسل من [[Python/str|صفوف]] مزدوجة تتضمن زوج مفتاح/قيمة، أو ربط mapping (مثل: [[Python/defining functions|القاموس]]) أسماء بقيم. 
 +
 +
يتيح الخياران الأخيران إسناد قيم متنوعة إلى enumerations، في حين تسند الخيارات الأخرى وبصورة تلقائية أعدادًا صحيحة تبدأ من الرقم <code>1</code> (يمكن استخدام المعامل <code>start</code> لتحديد قيمة ابتدائية مختلفة)، ويعاد صنف جديد مشتّق من الصنف Enum.
 +
 +
وبعبارة أخرى فإنّ عملية الإسناد في المثال السابقة إلى الصنف <code>Animal</code> تكون مكافئة لما يلي:<syntaxhighlight lang="python3">
 +
>>> class Animal(Enum):
 +
...     ANT = 1
 +
...     BEE = 2
 +
...     CAT = 3
 +
...     DOG = 4
 +
...
 +
</syntaxhighlight>إن السبب الذي يدعو إلى البدء بالعدد <code>1</code> وليس <code>0</code> هو أنّ العدد <code>0</code> يمثّل القيمة <code>False</code> في السياقات البوليانية، لكنّ جميع عناصر <code>enum</code> تُعالج إلى القيمة <code>True</code>.
 +
 +
إجراء عملية Pickling على enums أنشئت بواسطة الواجهة البرمجية الوظيفية قد يكون صعبًا في بعض الأحيان، وذلك لأنّ frame stack implementation details تستخدم لمعرفة الوحدة التي أنشئ فيها enumeration (على سبيل المثال ستفشل العملية عند استخدام دالة مساعدة في وحدة أخرى، وقد لا تتم العملية أيضًا على IronPython أو Jython).
 +
 +
وحل هذه المشكلة هو تحديد اسم الوحدة وعلى النحو التالي:<syntaxhighlight lang="python3">
 +
>>> Animal = Enum('Animal', 'ANT BEE CAT DOG', module=__name__)
 +
</syntaxhighlight>'''تحذير:'''
 +
 +
إن لم تُعرّف الوحدة المستخدمة، ولم يتمكن الصنف Enum من تحديدها، فبالإمكان إجراء عملية unpickling على عناصر Enum، ولكن لتقريب الأخطاء إلى مصادرها، فإنّ عملية pickling هي التي ستعطل.
 +
 +
كذلك يعتمد البروتوكول الرابع الجديد الخاص بعملية pickling -في بعض الحالات- على التابع <code>‎__qualname__‎</code> والذي يُعيّن الموقع الذي تكون فيه عملية pickling قادرة على إيجاد الصنف. فمثلًا، إن كان الصنف موجودًا في صنف <code>SomeData</code> ضمن النطاق العام:<syntaxhighlight lang="python3">
 +
>>> Animal = Enum('Animal', 'ANT BEE CAT DOG', qualname='SomeData.Animal')
 +
</syntaxhighlight>والتوقيع الكامل هو:<syntaxhighlight lang="python3">
 +
Enum(value='NewEnumName', names=<...>, *, module='...', qualname='...', type=<mixed-in class>, start=1)
 +
</syntaxhighlight>
 +
 +
value:
 +
 +
القيمة التي سيسجّلها الصنف Enum كاسم له.
 +
 +
names:
 +
 +
عناصر الصنف Enum. يمكن أن يكون سلسلة نصية تتضمن أسماء مفصولة بمسافات بيضاء أو بفواصل (القيم تبدأ بالرقم 1 إلا إذا حُدّد عدد آخر كعدد ابتدائي):
 +
 +
'RED GREEN BLUE' | 'RED,GREEN,BLUE' | 'RED, GREEN, BLUE'
 +
 +
أو كقائمة من الأسماء:
 +
 +
['RED', 'GREEN', 'BLUE']
 +
 +
أو كقائمة من أزواج (اسم، قيمة):
 +
 +
[('CYAN', 4), ('MAGENTA', 5), ('YELLOW', 6)]
 +
 +
أو كقاموس:
 +
 +
{'CHARTREUSE': 7, 'SEA_GREEN': 11, 'ROSEMARY': 42}
 +
 +
module:
 +
 +
اسم الوحدة التي يمكن إيجاد الصنف Enum الجديد فيها.
 +
 +
qualname:
 +
 +
المكان الذي يمكن إيجاد الصنف Enum الجديد فيه ضمن الوحدة.
 +
 +
type:
 +
 +
النوع المطلوب دمجه مع صنف Enum الجديد.
 +
 +
start:
 +
 +
العدد الذي يبدأ منه العدّ عند تمرير الأسماء فقط.
 +
 +
<nowiki>'''</nowiki>ملاحظة<nowiki>'''</nowiki>: أضيف المعامل start في الإصدار 3.5 من بايثون.
  
 
== انظر أيضًا ==
 
== انظر أيضًا ==

مراجعة 09:31، 12 يوليو 2018

enumeration هو مجموعة من الأسماء الرمزية (العناصر) المرتبطة بقيم ثابتة وفريدة. يمكن مقارنة عناصر enumeration عن طريق هويتها، ويمكن المرور على عناصر enumeration بواسطة حلقة تكرارية.

وحدة enum

تقدّم وحدة enum أربعة أصناف enumeration يمكن استخدامها لتعريف مجموعة فريدة من الأسماء والقيم، وهذه الأصناف هي: Enum و IntEnum و Flag و IntFlag. وإلى جانب ما سبق تقدّم الوحدة مزخرفًا واحدًا هو unique()‎، وصنفًا مساعدًا واحدًا هو auto.

الصنف enum.Enum

هو الصنف الأساسي والذي يستخدم لإنشاء ثوابت معدّدة enumerated constants. راجع قسم الواجهة البرمجية الوظيفية للاطلاع على الصيغة البديلة.

الصنف enum.IntEnum

الصنف الأساسي الذي يستخدم لإنشاء ثوابت معدّدة تكون كذلك أصنافًا فرعية للصنف int.

الصنف enum.IntFlag

الصنف الأساسي الذي يستخدم لإنشاء ثوابت معدّدة يمكن دمجها مع بعضها البعض باستخدم عامل bitwise دون التأثير على كونها عناصر للصنف IntFlag. وتكون عناصر IntFlag أصنافًا فرعية من الصنف int أيضًا. 

الصنف enum.Flag

الصنف الرئيسي الذي يستخدم لإنشاء ثوابت معدّدة يمكن دمجها مع بعضها البعض دون التأثير على كونها من نوع Flag.

المزخرف enum.unique()‎

مزخرف الصنف Enum والذي يضمن ارتباط اسم واحد بقيمة واحدة فقط.

الصنف المساعد enum.auto

عند استخدام هذا الصنف تُستبدل نسخ الصنف Enum بقيم ملائمة.

ملاحظة: الأصناف Flag و IntFlag و auto جديدة في الإصدار 3.6 من بايثون.

إنشاء Enum

يمكن إنشاء Enumeration باستخدام الصيغة الخاصّة بإنشاء الأصناف في بايثون، الأمر الذي يسهّل قراءة وكتابة هذا النوع من البيانات، ويوضح المثال التالي طريقة تعريف enumeration:

>>> from enum import Enum
>>> class Color(Enum):
...     RED = 1
...     GREEN = 2
...     BLUE = 3

ملاحظة: قيم عناصر Enumeration

يمكن استخدام أي نوع من البيانات (الأعداد الصحيحة، والسلاسل النصية) كقيمة لعناصر enumeration. إن كانت القيمة المضبوطة غير مهمّة فيمكن استخدام نسخ auto وستختار اللغة القيمة الملائمة، ولكن يجب الانتباه عند استخدام auto مع قيم أخرى.

ملاحظة: التسمية

  • الصنف Color هو enumeration (أو enum)
  • الخاصيات Color.RED، Color.GREEN وغيرها هي عناصر enumeration (أو عناصر enum) وهي قيم ثابتة.
  • تمتلك عناصر enum أسماء وقيم (اسم Color.RED هو RED، وقيمة Color.BLUE هي 3).

ملاحظة:

صحيح أن تعريف Enumerations يكون باستخدام صيغة تعريف الأصناف، إلا أنّ Enums لا تعدّ أصنافًا اعتيادية في بايثون. 

تمتلك عناصر Enumeration تمثيلًا نصّيًا قابلًا للقراءة:

>>> print(Color.RED)
Color.RED

في حين تعطي الدالة repr() معلومات أكثر:

>>> print(repr(Color.RED))
<Color.RED: 1>

أما نوع العنصر فهو الـ enumeration الذي ينتمي إليه:

>>> type(Color.RED)
<enum 'Color'>
>>> isinstance(Color.GREEN, Color)
True
>>>

تمتلك عناصر Enum خاصّية تحمل اسم العنصر فقط:

>>> print(Color.RED.name)
RED

تدعم Enumeration المرور على العناصر بحسب ترتيب تعريفها:

>>> class Shake(Enum):
...     VANILLA = 7
...     CHOCOLATE = 4
...     COOKIES = 9
...     MINT = 3
...
>>> for shake in Shake:
...     print(shake)
...
Shake.VANILLA
Shake.CHOCOLATE
Shake.COOKIES
Shake.MINT

عناصر Enumeration قابلة للتقطيع (hashable)؛ لذا يمكن استخدامها في القواميس والمجموعات:

>>> apples = {}
>>> apples[Color.RED] = 'red delicious'
>>> apples[Color.GREEN] = 'granny smith'
>>> apples == {Color.RED: 'red delicious', Color.GREEN: 'granny smith'}
True

الوصول إلى عناصر Enumeration وخواصّها برمجيًا

من المفيد في بعض الأحيان الوصول إلى عناصر Enumeration برمجيًّا (بمعنى أنّه لا يمكن استخدام أسماء محدّدة مثل Color.RED لأنّه اللون المطلوب قد يكون غير معروف أثناء كتابة البرنامج) ويمكن القيام بذلك كما يلي:

>>> Color(1)
<Color.RED: 1>
>>> Color(3)
<Color.BLUE: 3>

ويمكن الوصول إلى عناصر enum بواسطة أسمائها كما يلي:

>>> Color['RED']
<Color.RED: 1>
>>> Color['GREEN']
<Color.GREEN: 2>

للحصول على اسم أو قيمة عنصر من عناصر enum:

>>> member = Color.RED
>>> member.name
'RED'
>>> member.value
1

مضاعفة عناصر وقيم enum

لا تسمح اللغة بوجود عنصري enum يحملان نفس الاسم:

>>> class Shape(Enum):
...     SQUARE = 2
...     SQUARE = 3
...
Traceback (most recent call last):
...
TypeError: Attempted to reuse key: 'SQUARE'

ولكن يمكن لعنصري enum أن يمتلكا القيمة ذاتها. لو فرضنا وجود عنصرين A و B يحملان القيمة ذاتها (وكان A معرّفًا قبل B) فإن العنصر B سيكون اختصارًا (alias، أو اسمًا بديلًا) للعنصر A. إن جرى الاستعلام عن قيمة A و B فإنّ النتيجة ستكون A، وإن جرى الاستعلام عن اسم B فإن النتيجة ستكون A أيضًا:

>>> class Shape(Enum):
...     SQUARE = 2
...     DIAMOND = 1
...     CIRCLE = 3
...     ALIAS_FOR_SQUARE = 2
...
>>> Shape.SQUARE
<Shape.SQUARE: 2>
>>> Shape.ALIAS_FOR_SQUARE
<Shape.SQUARE: 2>
>>> Shape(2)
<Shape.SQUARE: 2>

ملاحظة: لا يمكن إنشاء عنصر يحمل اسم خاصّية معرّفة مسبقًا (عنصر آخر، أو تابع ...إلخ.) كما لا يمكن إنشاء خاصّية تحمل نفس اسم عنصر معرّف مسبقًا.

ضمان فرادة قيم enumeration

تسمح enumerations - افتراضيًّا - باستخدام أسماء متعددة كمختصرات للقيمة نفسها. إن كان هذا الأسلوب غير مرغوب به فيمكن استخدام المزخرف التالي لضمان استخدام كلّ قيمة في الـ enumeration لمرة واحدة فقط:

@enum.unique

يوضح المثال التالي كيفية استخدام هذا المزخرف (decorator):

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

استخدام القيم التلقائية

إن كانت القيمة الدقيقة غير مهمّة فيمكن استخدام auto محلّها:

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

تختار اللغة القيم عن طريق التابع ‎_generate_next_value_()‎ والذي يمكن إعادة تعريفه (override):

>>> class AutoName(Enum):
...     def _generate_next_value_(name, start, count, last_values):
...         return name
...
>>> class Ordinal(AutoName):
...     NORTH = auto()
...     SOUTH = auto()
...     EAST = auto()
...     WEST = auto()
...
>>> list(Ordinal)
[<Ordinal.NORTH: 'NORTH'>, <Ordinal.SOUTH: 'SOUTH'>, <Ordinal.EAST: 'EAST'>, <Ordinal.WEST: 'WEST'>]

المرور على عناصر enumeration

لا تقدم عملية المرور على عناصر enumeration الاختصارات الموجودة فيه:

>>> list(Shape)
[<Shape.SQUARE: 2>, <Shape.DIAMOND: 1>, <Shape.CIRCLE: 3>]

الخاصّية الخاصة __members__ هي قاموس مرتّب يربط الأسماء بالعناصر، ويتضمن جميع الأسماء المعرّفة في enumeration وبضمنها الاختصارات:

>>> for name, member in Shape.__members__.items():
...     name, member
...
('SQUARE', <Shape.SQUARE: 2>)
('DIAMOND', <Shape.DIAMOND: 1>)
('CIRCLE', <Shape.CIRCLE: 3>)
('ALIAS_FOR_SQUARE', <Shape.SQUARE: 2>)

يمكن الاستفادة من الخاصية __members__ للوصول إلى عناصر enumeration برمجيًّا. فعلى سبيل المثال يمكن العثور على جميع الاختصارات بالطريقة التالية:

>>> [name for name, member in Shape.__members__.items() if member.name != name]
['ALIAS_FOR_SQUARE']

مقارنة العناصر

يمكن عقد المقارنات بين عناصر enumeration باستخدام هوية العنصر:

>>> Color.RED is Color.RED
True
>>> Color.RED is Color.BLUE
False
>>> Color.RED is not Color.BLUE
True

لا تدعم اللغة المقارنات المرتّبة بين قيم enumeration، إلى جانب أنّ عناصر Enum ليست أعدادًا صحيحة.

>>> Color.RED < Color.BLUE
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'Color' and 'Color'

ولكن يمكن إجراء اختبارات المساواة:

>>> Color.BLUE == Color.RED
False
>>> Color.BLUE != Color.RED
True
>>> Color.BLUE == Color.BLUE
True

عقد المقارنة مع قيم ليست ضمن enumeration تكون نتيجتها دومًا عدم المساواة:

>>> Color.BLUE == 2
False

العناصر والخصائص المسموح بها في enumeration

في الأمثلة السابقة كانت قيم enumeration أعدادًا صحيحة. بالرغم من أن استخدام الأعداد الصحيحة مختصر وسريع، ولكنّه ليس إلزاميًا. في أغلب الحالات ليس من المهمّ معرفة القيمة الحقيقية للـ enumeration، ولكن إن كانت القيمة مهمّة، فيمكن للـ enumerations أن تمتلك أيّ قيمة ممكنة.

Enumerations هي أصناف بايثون؛ لذا يمكن أن تمتلك توابع وتوابع خاصّة كما هو الحال مع الأصناف، فلو كان لدينا الـ enumeration التالي:

>>> class Mood(Enum):
...     FUNKY = 1
...     HAPPY = 3
...
...     def describe(self):
...         # self is the member here
...         return self.name, self.value
...
...     def __str__(self):
...         return 'my custom str! {0}'.format(self.value)
...
...     @classmethod
...     def favorite_mood(cls):
...         # cls here is the enumeration
...         return cls.HAPPY
...

فيمكن حينئذ كتابة الشيفرة التالية:

>>> Mood.favorite_mood()
<Mood.HAPPY: 3>
>>> Mood.HAPPY.describe()
('HAPPY', 3)
>>> str(Mood.FUNKY)
'my custom str! 1'

تتبع عملية التسمية القواعد التالية:

  • تكون الأسماء التي تبدأ وتنتهي بشرطة سفلية واحدة محجوزة من طرف enum ولا يمكن استخدامها. 
  • تصبح جميع الخاصيات الأخرى المعرّفة ضمن enumeration عناصر له؛ باستثناء التوابع الخاصة (‎__str__()، __add__()‎، وغيرها) والواصفات (descriptors) (التوابع واصفات أيضًا).

التفريع المقيد لأصناف enum

تسمح اللغة فقط بإنشاء أصناف فرعية للـ enumeration التي لا تعرّف أي عناصر، ولهذا تعدّ الشيفرة التالية خاطئة:

>>> class MoreColor(Color):
...     PINK = 17
...
Traceback (most recent call last):
...
TypeError: Cannot extend enumerations

أما الشيفرة التالية فصحيحة:

>>> class Foo(Enum):
...     def some_behavior(self):
...         pass
...
>>> class Bar(Foo):
...     HAPPY = 1
...     SAD = 2

يؤدي السماح بإنشاء أصناف فرعية للصنف enum الذي يمتلك عددًا من العناصر إلى مخالفة بعض الثوابت المهمّة في الأنواع ونسخ الأصناف، ولكن من جانب آخر من المعقول أن يُسمح بمشاركة بعض الأمور المشتركة بين مجموعة من الـ enumeration.

(راجع OrderedEnum للاطلاع على الأمثلة).

عملية Pickling

يمكن إجراء عمليتي pickling و unpickling على enumerations:

>>> from test.test_enum import Fruit
>>> from pickle import dumps, loads
>>> Fruit.TOMATO is loads(dumps(Fruit.TOMATO))
True

وتنطبق هنا جميع القيود المعروفة لعملية pickling: حيث يجب تعريف الـ enums في المستوى الأعلى من الوحدة؛ وذلك لأنّ عملية unpickling تتطلب كون هذه الـ enums قابلة للاستيراد من تلك الوحدة.

ملاحظة: من الممكن بالاعتماد على الإصدار الرابع من بروتوكول عملية pickling إجراء هذه العملية على enums متداخلة في أصناف أخرى.

من الممكن تعديل طريقة إجراء عمليتي pickling و unpickling على عناصر الصنف Enum وذلك بتعريف التابع ‎__reduce_ex__()‎ في صنف enumeration.

الواجهة البرمجية الوظيفية Functional API

الصنف Enum قابل للاستدعاء، ويقدّم الواجهة البرمجية الوظيفية التالية:

>>> Animal = Enum('Animal', 'ANT BEE CAT DOG')
>>> Animal
<enum 'Animal'>
>>> Animal.ANT
<Animal.ANT: 1>
>>> Animal.ANT.value
1
>>> list(Animal)
[<Animal.ANT: 1>, <Animal.BEE: 2>, <Animal.CAT: 3>, <Animal.DOG: 4>]

هذه الواجهة البرمجية مشابهة للصفوف المسمّاة، ويكون المعامل الأول في عملية استدعاء الصنف Enum هو اسم enumeration.

أما المعامل الثاني source فهو مصدر أسماء عناصر enumeration. يمكن لهذا المعامل أن يكون سلسلة نصية تتضمن أسماء مفصولة عن بعضها البعض بمسافات بيضاء، أو تسلسل من الأسماء، أو تسلسل من صفوف مزدوجة تتضمن زوج مفتاح/قيمة، أو ربط mapping (مثل: القاموس) أسماء بقيم. 

يتيح الخياران الأخيران إسناد قيم متنوعة إلى enumerations، في حين تسند الخيارات الأخرى وبصورة تلقائية أعدادًا صحيحة تبدأ من الرقم 1 (يمكن استخدام المعامل start لتحديد قيمة ابتدائية مختلفة)، ويعاد صنف جديد مشتّق من الصنف Enum.

وبعبارة أخرى فإنّ عملية الإسناد في المثال السابقة إلى الصنف Animal تكون مكافئة لما يلي:

>>> class Animal(Enum):
...     ANT = 1
...     BEE = 2
...     CAT = 3
...     DOG = 4
...

إن السبب الذي يدعو إلى البدء بالعدد 1 وليس 0 هو أنّ العدد 0 يمثّل القيمة False في السياقات البوليانية، لكنّ جميع عناصر enum تُعالج إلى القيمة True.

إجراء عملية Pickling على enums أنشئت بواسطة الواجهة البرمجية الوظيفية قد يكون صعبًا في بعض الأحيان، وذلك لأنّ frame stack implementation details تستخدم لمعرفة الوحدة التي أنشئ فيها enumeration (على سبيل المثال ستفشل العملية عند استخدام دالة مساعدة في وحدة أخرى، وقد لا تتم العملية أيضًا على IronPython أو Jython).

وحل هذه المشكلة هو تحديد اسم الوحدة وعلى النحو التالي:

>>> Animal = Enum('Animal', 'ANT BEE CAT DOG', module=__name__)

تحذير:

إن لم تُعرّف الوحدة المستخدمة، ولم يتمكن الصنف Enum من تحديدها، فبالإمكان إجراء عملية unpickling على عناصر Enum، ولكن لتقريب الأخطاء إلى مصادرها، فإنّ عملية pickling هي التي ستعطل.

كذلك يعتمد البروتوكول الرابع الجديد الخاص بعملية pickling -في بعض الحالات- على التابع ‎__qualname__‎ والذي يُعيّن الموقع الذي تكون فيه عملية pickling قادرة على إيجاد الصنف. فمثلًا، إن كان الصنف موجودًا في صنف SomeData ضمن النطاق العام:

>>> Animal = Enum('Animal', 'ANT BEE CAT DOG', qualname='SomeData.Animal')

والتوقيع الكامل هو:

Enum(value='NewEnumName', names=<...>, *, module='...', qualname='...', type=<mixed-in class>, start=1)

value:

القيمة التي سيسجّلها الصنف Enum كاسم له.

names:

عناصر الصنف Enum. يمكن أن يكون سلسلة نصية تتضمن أسماء مفصولة بمسافات بيضاء أو بفواصل (القيم تبدأ بالرقم 1 إلا إذا حُدّد عدد آخر كعدد ابتدائي):

'RED GREEN BLUE' | 'RED,GREEN,BLUE' | 'RED, GREEN, BLUE'

أو كقائمة من الأسماء:

['RED', 'GREEN', 'BLUE']

أو كقائمة من أزواج (اسم، قيمة):

[('CYAN', 4), ('MAGENTA', 5), ('YELLOW', 6)]

أو كقاموس:

{'CHARTREUSE': 7, 'SEA_GREEN': 11, 'ROSEMARY': 42}

module:

اسم الوحدة التي يمكن إيجاد الصنف Enum الجديد فيها.

qualname:

المكان الذي يمكن إيجاد الصنف Enum الجديد فيه ضمن الوحدة.

type:

النوع المطلوب دمجه مع صنف Enum الجديد.

start:

العدد الذي يبدأ منه العدّ عند تمرير الأسماء فقط.

'''ملاحظة''': أضيف المعامل start في الإصدار 3.5 من بايثون.

انظر أيضًا

مصادر