跳转到主要内容

Python的Enum,具有额外的功能,可以很好地与标签和选择字段协同工作

项目描述

https://img.shields.io/pypi/v/choicesenum.svg https://travis-ci.org/loggi/python-choicesenum.svg?branch=master Documentation Status https://coveralls.io/repos/github/loggi/python-choicesenum/badge.svg?branch=master

Python的Enum,具有额外的功能,可以很好地与标签和选择字段协同工作。

安装

使用pip安装 choicesenum

$ pip install choicesenum

特性

  • 可以用于创建常量组的 ChoicesEnum

  • ChoicesEnum 可以定义用于 choices 字段标签。

  • 包含Django字段: EnumCharFieldEnumIntegerField

  • 所有 ChoicesEnum 类型都可以直接与它们的原始值进行比较。

  • 支持(已测试)Python 2.7、3.5、3.6、3.7和3.8。

  • 支持(已测试)Django 1.9、1.10、1.11、2.0、2.1、2.2和3.0。

使用示例

使用 HttpStatuses 的示例

class HttpStatuses(ChoicesEnum):
    OK = 200
    BAD_REQUEST = 400
    UNAUTHORIZED = 401
    FORBIDDEN = 403

使用 Colors 的示例

from choicesenum import ChoicesEnum

class Colors(ChoicesEnum):
    RED = '#f00', 'Vermelho'
    GREEN = '#0f0', 'Verde'
    BLUE = '#00f', 'Azul'

比较

所有 Enum 类型都可以与它们的值进行比较

assert HttpStatuses.OK == 200
assert HttpStatuses.BAD_REQUEST == 400
assert HttpStatuses.UNAUTHORIZED == 401
assert HttpStatuses.FORBIDDEN == 403

status_code = HttpStatuses.OK
assert 200 <= status_code <= 300

assert Colors.RED == '#f00'
assert Colors.GREEN == '#0f0'
assert Colors.BLUE == '#00f'

免费标签

所有 Enum 类型默认都有一个从枚举标识符派生的 display

assert HttpStatuses.OK.display == 'Ok'
assert HttpStatuses.BAD_REQUEST.display == 'Bad request'
assert HttpStatuses.UNAUTHORIZED.display == 'Unauthorized'
assert HttpStatuses.FORBIDDEN.display == 'Forbidden'

您可以使用元组轻松地为 Enum 项定义自己的自定义显示

class HttpStatuses(ChoicesEnum):
    OK = 200, 'Everything is fine'
    BAD_REQUEST = 400, 'You did a mistake'
    UNAUTHORIZED = 401, 'I know your IP'
    FORBIDDEN = 403

assert HttpStatuses.OK.display == 'Everything is fine'
assert HttpStatuses.BAD_REQUEST.display == 'You did a mistake'
assert HttpStatuses.UNAUTHORIZED.display == 'I know your IP'
assert HttpStatuses.FORBIDDEN.display == 'Forbidden'

动态属性

对于每个枚举项,都会生成一个动态属性 is_<enum_item>,以便进行快速布尔检查

color = Colors.RED
assert color.is_red
assert not color.is_blue
assert not color.is_green

该功能可用于避免将接收到的枚举值与已知的枚举项进行比较。

例如,您可以替换如下代码

# status = HttpStatuses.BAD_REQUEST

def check_status(status):
    if status == HttpStatuses.OK:
        print("Ok!")

为如下

def check_status(status):
    if status.is_ok:
        print("Ok!")

自定义方法和属性

您可以声明自定义属性和方法

class HttpStatuses(ChoicesEnum):
    OK = 200, 'Everything is fine'
    BAD_REQUEST = 400, 'You did a mistake'
    UNAUTHORIZED = 401, 'I know your IP'
    FORBIDDEN = 403

    @property
    def is_error(self):
        return self >= self.BAD_REQUEST

assert HttpStatuses.OK.is_error is False
assert HttpStatuses.BAD_REQUEST.is_error is True
assert HttpStatuses.UNAUTHORIZED.is_error is True

迭代

枚举类型是可迭代的

>>> for color in Colors:
...     print(repr(color))
Color('#f00').RED
Color('#0f0').GREEN
Color('#00f').BLUE

顺序仅在py3.4+中保证。对于py2.7中的固定顺序,您可以实现一个魔术属性 _order_

from choicesenum import ChoicesEnum

class Colors(ChoicesEnum):
    _order_ = 'RED GREEN BLUE'

    RED = '#f00', 'Vermelho'
    GREEN = '#0f0', 'Verde'
    BLUE = '#00f', 'Azul'

选择

使用 .choices() 方法接收一个包含元组 (item, display) 的列表

assert list(Colors.choices()) == [
    ('#f00', 'Vermelho'),
    ('#0f0', 'Verde'),
    ('#00f', 'Azul'),
]

使用 .values() 方法接收一个包含内部值的列表

assert Colors.values() == ['#f00', '#0f0', '#00f', ]

选项

即使 ChoicesEnum 类本身就是一个迭代器,您也可以使用 .options() 将枚举项转换为列表

assert Colors.options() == [Colors.RED, Colors.GREEN, Colors.BLUE]

字典样式的get

使用 .get(value, default=None) 方法接收 default,如果 value 不是枚举项

assert Colors.get(Colors.RED) == Colors.RED
assert Colors.get('#f00') == Colors.RED
assert Colors.get('undefined_color') is None
assert Colors.get('undefined_color', Colors.RED) == Colors.RED

兼容性

枚举项可以在需要值时使用

assert u'Currrent color is {c} ({c.display})'.format(c=color) ==\
       u'Currrent color is #f00 (Vermelho)'

即使在字典和集合中,因为它与其值的 hash() 相同

d = {
    HttpStatuses.OK.value: "using value",
    HttpStatuses.BAD_REQUEST: "using enum",
    401: "from original value",
}
assert d[HttpStatuses.OK] == "using value"
assert d[HttpStatuses.BAD_REQUEST.value] == "using enum"
assert d[HttpStatuses.OK] == d[HttpStatuses.OK.value]
assert d[HttpStatuses.UNAUTHORIZED] == d[401]

还有内嵌类型的乐观转换

assert int(HttpStatuses.OK) == 200
assert float(HttpStatuses.OK) == 200.0
assert str(HttpStatuses.BAD_REQUEST) == "400"

检查成员资格

assert HttpStatuses.OK in HttpStatuses
assert 200 in HttpStatuses
assert 999 not in HttpStatuses

JSON

如果您想进行JSON序列化,您至少有两个选项

  1. 修复默认序列化器。

  2. 编写自定义JSONEncoder。

ChoicesEnum附带一个方便的修复函数,您需要将此代码添加到顶部以自动添加JSON序列化功能

from choicesenum.patches import patch_json
patch_json()

Django

字段

使用自定义Django字段

from django.db import models
from choicesenum.django.fields import EnumCharField

class ColorModel(models.Model):
    color = EnumCharField(
        max_length=100,
        enum=Colors,
        default=Colors.GREEN,
    )

instance = ColorModel()
assert instance.color ==  Colors.GREEN
assert instance.color.is_green is True
assert instance.color.value == Colors.GREEN.value == '#0f0'
assert instance.color.display == Colors.GREEN.display

instance.color = '#f00'
assert instance.color == '#f00'
assert instance.color.value == '#f00'
assert instance.color.display == 'Vermelho'

保证字段值始终是 ChoicesEnum 项。请注意,字段将只接受使用中的 Enum 的有效值,因此如果您的字段允许 null,则枚举也应如此

from django.db import models
from choicesenum import ChoicesEnum
from choicesenum.django.fields import EnumIntegerField

class UserStatus(ChoicesEnum):
    UNDEFINED = None
    PENDING = 1
    ACTIVE = 2
    INACTIVE = 3
    DELETED = 4


class User(models.Model):
    status = EnumIntegerField(enum=UserStatus, null=True, )

instance = User()
assert instance.status.is_undefined is True
assert instance.status.value is None
assert instance.status == UserStatus.UNDEFINED
assert instance.status.display == 'Undefined'

# again...
instance.status = None
assert instance.status.is_undefined is True

Graphene

Graphene 枚举一起使用

UserStatusEnum = graphene.Enum.from_enum(UserStatus)

Schematics

Schematics 枚举一起使用

from schematics.models import Model as SchematicModel
from schematics.types import StringType, DateTimeType
from choicesenum import ChoicesEnum
from choicesenum.schematics.types import ChoicesEnumType

class HttpStatus(ChoicesEnum):
    OK = 200
    BAD_REQUEST = 400
    UNAUTHORIZED = 401
    FORBIDDEN = 403

class CustomSchematicModel(SchematicModel):
    name = StringType(required=True, max_length=255)
    created = DateTimeType(required=True, formats=('%d/%m/%Y', ''))
    http = ChoicesEnumType(HttpStatuses, required=True)

历史

0.7.0 (2020-08-02)

  • 添加对Django 3.0的支持(感谢 @klette)。

  • 停止支持Python 3.4。

  • 修复在Django Admin中使用Django EnumIntegerField时的问题。

0.6.0 (2019-09-05)

  • 添加schematics contrib类型ChoicesEnumType。

  • 停止支持Django 1.6、1.7、1.8。

0.5.3 (2019-02-06)

  • 修复Django 1.7+的默认值迁移。

0.5.2 (2019-01-18)

  • 优化成员检查和动态创建 is_<name> 属性。

0.5.1 (2019-01-04)

  • 修复readme RST(需要新的Pypi上传)。

0.5.0 (2019-01-04)

  • 成员测试(项在枚举中)返回原始值的有效结果。

  • 添加新的字典样式的 .get 方法,能够返回默认值(感谢 @leandrogs)。

  • Django:支持Postgres数组函数和查询(感谢 @tomfa)。

  • Django:支持使用 queryset.defer() 延迟枚举字段(感谢 @noamkush)。

  • Django:2.1支持。

0.4.0 (2018-07-13)

  • 优化内嵌类型的乐观转换(感谢 @gabisurita)。

  • 可选stdlib补丁以自动支持JSON序列化。

  • 将Python3.7添加到测试矩阵。

0.3.0 (2018-06-22)

  • 官方Django 2.0支持(0.2.2也工作得很好)。

  • ChoicesEnum 与其值具有相同的 hash()。可用于在字典中检索/恢复项(d[enum] == d[enum.value])。

0.2.2 (2017-12-01)

  • 修复:通过 select_related 进行查询时,无需定义 None 值(感谢 @klette)。

0.2.1 (2017-09-30)

  • 修复Django 1.6的South迁移。

0.2.0 (2017-09-11)

  • ChoicesEnum 项可以通过其值进行比较(==,!=,>,>=,<,<=)(感谢 @jodal)。

  • +``ChoicesEnum.values``: 返回枚举的所有原始值(例如: [x.value for x in Enum])。

0.1.7 (2017-09-10)

  • 修复: ChoicesEnum 现在是可哈希的(感谢 @jodal)。

0.1.6 (2017-09-08)

  • 修复:将 __len__ 调用代理到内部枚举值。

0.1.5 (2017-09-05)

  • ChoicesEnum.description: 别名于 label,允许枚举描述符被Graphene使用。

0.1.4 (2017-08-28)

  • 修复Django 1.6的South迁移。

  • ChoicesEnum repr可用于重建实例(item == eval(repr(item)))。

0.1.3 (2017-08-28)

  • 修复sdist不包括子模块(django contrib)。

0.1.2 (2017-08-27)

  • README修复和改进。

0.1.0 (2017-08-27)

  • 在PyPI上的首次发布。

项目详情


下载文件

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

源分布

choicesenum-0.7.0.tar.gz (25.2 kB 查看哈希值)

上传时间

构建分布

choicesenum-0.7.0-py2.py3-none-any.whl (12.1 kB 查看哈希值)

上传时间 Python 2 Python 3

支持者