跳转到主要内容

扩展Python 3 enum模块的枚举类

项目描述

extenum

Build Status Latest Version Downloads License

为Python 3 enum模块扩展枚举类。

自从3.4版本以来,已经增加了enum模块。这对于简单使用来说已经足够好了。extenum深受Effective Java中描述的Java Enum风格的启发,并提供了一些额外的功能。

如何安装

$ pip install extenum

常量特定枚举

常量特定枚举类继承自标准枚举类,并为枚举成员提供了常量特定方法和函数重载的功能。

阅读Effective Java以获取更多详细信息。

常量特定方法实现

让我们尝试使用常量特定枚举创建枚举类。要使用方法作为函数重载,在该方法上添加@overload(CONSTANT)装饰器。如您在隐式枚举部分中稍后所见,overload装饰器是隐式定义的。

>>> from extenum import ConstantSpecificEnum
>>> class Operation(ConstantSpecificEnum):
...     PLUS = '+'
...     MINUS = '-'
...     TIMES = '*'
...     DIVIDE = '/'
...
...     @overload(PLUS)
...     def apply(self, x, y):
...         return x + y
...
...     @overload(MINUS)
...     def apply(self, x, y):
...         return x - y
...
...     @overload(TIMES)
...     def apply(self, x, y):
...         return x * y
...
...     @overload(DIVIDE)
...     def apply(self, x, y):
...         return x / y
...
>>> for name, const in Operation.__members__.items():
...     print(name, ':', const.apply(2, 4))
...
PLUS : 6
MINUS : -2
TIMES : 8
DIVIDE : 0.5

策略枚举模式

策略枚举是基于常量特定方法的更复杂模式。

>>> from extenum import ConstantSpecificEnum
>>> class PayrollDay(ConstantSpecificEnum):
...
...     class PayType(ConstantSpecificEnum):
...         WEEKDAY = 1
...         WEEKEND = 2
...
...         @overload(WEEKDAY)
...         def overtime_pay(self, hours, pay_rate):
...             return 0 if hours <= 8 else (hours - 8) * pay_rate / 2
...
...         @overload(WEEKEND)
...         def overtime_pay(self, hours, pay_rate):
...             return hours * pay_rate / 2
...
...         def pay(self, hours_worked, pay_rate):
...             base_pay = hours_worked * pay_rate
...             overtime_pay = self.overtime_pay(hours_worked, pay_rate)
...             return base_pay + overtime_pay
...
...     MONDAY = PayType.WEEKDAY
...     TUESDAY = PayType.WEEKDAY
...     WEDNESDAY = PayType.WEEKDAY
...     THURSDAY = PayType.WEEKDAY
...     FRIDAY = PayType.WEEKDAY
...     SATURDAY = PayType.WEEKEND
...     SUNDAY = PayType.WEEKEND
...
...     def pay(self, hours_worked, pay_rate):
...         return self.value.pay(hours_worked, pay_rate)
...
>>> PayrollDay.MONDAY.pay(10, 1000.0)
11000.0
>>> PayrollDay.WEDNESDAY.pay(8, 1000.0)
8000.0
>>> PayrollDay.SATURDAY.pay(10, 1000.0)
15000.0
>>> PayrollDay.SUNDAY.pay(8, 1000.0)
12000.0

隐式枚举

在描述隐式枚举类之前,请阅读Nick Coghlan撰写的以下优秀文章。

好的。我想你已经理解了为什么标准枚举模块没有支持隐式声明语法。

暂时抛开它的需求,Nick 指出了如何实现 ImplicitEnum。所以,让我们尝试使用特殊方法,在 defaultdict 中使用 __missing__ 和在元类中使用 __prepare__ 来实验性地实现它。

>>> from extenum import ImplicitEnum
>>> class Color(ImplicitEnum):
...     RED
...     GREEN
...     BLUE
...
>>> for name, const in Color.__members__.items():
...     print(name, ':', const.value)
...
RED : 1
GREEN : 2
BLUE : 3

如果一些常量是显式的,而其余的是隐式的,它将工作得很好。

>>> class Numbers(ImplicitEnum):
...     ONE = 1
...     TWO = 2
...     THREE
...
>>> Numbers.THREE.value
3

然而,它依赖于声明的顺序。

>>> class DuplicatedValues(ImplicitEnum):
...     ONE
...     TWO = 1
...     THREE = 1
...
>>> DuplicatedValues.ONE.value
1
>>> DuplicatedValues.TWO.value
1
>>> DuplicatedValues.THREE.value
1

EnumSet

EnumSet 是 Set 接口针对枚举类型的专用实现之一,灵感来源于 Java EnumSet

它提供了处理多个枚举常量的实用函数。

>>> from enum import Enum
>>> from extenum import EnumSet
>>> class Mode(Enum):
...     READ = 4
...     WRITE = 2
...     EXECUTE = 1
...
...     @classmethod
...     def set_of(cls, values):
...         opts = EnumSet.none_of(cls)
...         for value in values:
...             opts.add(cls(value))
...         return opts
...
>>> Mode.set_of([4, 2])  # doctest: +SKIP
EnumSet({<Mode.READ: 4>, <Mode.WRITE: 2>})

创建包含所有枚举成员的 EnumSet

>>> EnumSet.all_of(Mode)  # doctest: +SKIP
EnumSet({<Mode.READ: 4>, <Mode.WRITE: 2>, <Mode.EXECUTE: 1>})

或者,创建包含任意枚举成员的 EnumSet

>>> enumset = EnumSet.of(Mode.READ, Mode.EXECUTE)
>>> enumset  # doctest: +SKIP
EnumSet({<Mode.READ: 4>, <Mode.EXECUTE: 1>})
>>> enumset.update(EnumSet.of(Mode.READ, Mode.WRITE))
>>> enumset  # doctest: +SKIP
EnumSet({<Mode.READ: 4>, <Mode.WRITE: 2>, <Mode.EXECUTE: 1>})

变更日志

0.8.1 (2020-11-07)

  • 改为使用 pytest-flake8 进行测试
  • 支持 python 3.6+

0.8.0 (2015-03-15)

  • 添加 EnumSet

0.7.0 (2015-03-06)

  • 为了简单起见,删除 RegisterFactory

0.6.0 (2015-03-05)

  • 添加 ImplicitEnum

0.5.0 (2015-03-01)

  • 第一个版本

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。

源代码分发

extenum-0.8.1.tar.gz (14.5 kB 查看哈希值)

上传时间 源代码

由以下支持