扩展Python 3 enum模块的枚举类
项目描述
extenum
为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 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 28aab227a8975543a18e2dbdef851ad5ea98a0c7dd4656cbb492f4d361498ed0 |
|
MD5 | 946fb4e6ee6e977ed9f31ded880136c4 |
|
BLAKE2b-256 | e7d7cc3515ce28502d118b722637e4553feca553584e622aaaf0747ed97ebac8 |