博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python,写一个简单的属于自己的『BaseEnum』类
阅读量:5844 次
发布时间:2019-06-18

本文共 2263 字,大约阅读时间需要 7 分钟。

Why do This

枚举,作为管理常量的有效手段之一,在各大主流语言中都有对应的语言级别的语法。但是在 Python 中没有这个语法,一般来说,大家比较倾向使用『module级别的常量』来处理,这种做法,自然既简单又粗暴又有效。但是如果需要管理大量常量,在常见的业务系统中,这个特别常见,仅仅使用上面的『三板斧』是有点不够的。

来看看 Python 3 标准库的 enum。嘴上说不要,心里确实很诚实,Python总算是将其加入到语言中了,虽然是以一种库的形式。首先我们来看看其使用方式:

import enumclass DirectionEnum(enum.IntEnum):    """    直接继承IntEnum,这是很常见的需求    """    UP = 1    DOWN = 2    LEFT = 3    RIGHT = 4class DirectionEnum2(enum.Enum):    """    继承更加底层的Enum类        让自己的实现更加灵活    """    UP = 'UP'    DOWN = 'DOWN'    LEFT = 'LEFT'    RIGHT = 'RIGHT'if __name__ == '__main__':    somevalue = 1    # 1. 第一种使用方式,OK,很符合我们的使用习惯,并且是work的    if somevalue == DirectionEnum.UP:        # 会运行, 猜测是, IntEnum内部做了一定的拆包动作        print('yes')    somevalue2 = 'UP'    # 2. 第一种使用方式,OK,很符合我们的使用习惯,然而得到的,却不是正确结果    if somevalue2 == DirectionEnum2.UP:        # 不会运行, 没有使用 .value        print('yes2')    # 3. 第三种使用方式,OK,并不是非常符合我们的习惯,但是,得到的预期结果是正确的    if somevalue2 == DirectionEnum2.UP.value:        # 运行, 使用了 .value        print('yes2')复制代码

从上面我们可以看到,如果仅仅是一些 int 类型的枚举集合,那么使用 IntEnum 是 OK 的。如果枚举集合的成分比较复杂,那么就要使用 Enum,虽然可以得到预期的正确结果,但是却要改改自己的使用习惯,强迫自己打出DirectionEnum2.UP.value这样的组合。

然而,作为脑瓜子不好使的人来说,DirectionEnum2.UP.value这种我很难记住,而且也不符合我的直觉啊,另外,我的大部分场景,只是需要『安安静静地使用一个枚举』而已,看 enum 库的内部实现,又是元类,又是委托啥的,各种高科技都用上了。所以,我们就有强大的动力,去适应自己,而不是适应别人。

How to do

考虑到我们的使用场景非常单一 & 简单,所以就想到了如下实现

import functoolsclass BaseEnum:    @classmethod    @functools.lru_cache(maxsize=1024)    def values(cls):        d = cls.__dict__        return [v                for k, v in d.items()                if (not k.startswith('_')) and k.isupper()]复制代码

然后使用之,这里我们通过写UT的形式去学习使用接口:

from unittest import TestCaseimport py3utilsclass DirectionEnum(py3utils.BaseEnum):    UP = 1    DOWN = 2    LEFT = 3    RIGHT = 4class TestBaseEnum(TestCase):    def test_values_is_list(self):        self.assertTrue(isinstance(DirectionEnum.values(), list))    def test_values(self):        e = [1, 2, 3, 4]        actual = DirectionEnum.values()        self.assertEqual(e, actual)    def test_enum(self):        actual = DirectionEnum.UP        expected = 1        self.assertEqual(actual, expected)复制代码

Finally

一些平时使用得比较趁手得代码 snippet,最好积累起来,放入自己特定得代码仓库中,以后想起来了,直接复用之即可。比如我, 就将上面得snippets 加入到自己的仓库中 https://github.com/hezhiming/py3utils,并佐以比较完善的的UT,以备不时之需。:)

转载地址:http://mnqcx.baihongyu.com/

你可能感兴趣的文章
win7 绑定arp
查看>>
产品经理书籍
查看>>
[Dart] Flutter开发中的几个常用函数
查看>>
Python这些位运算的妙用,绝对让你大开眼界
查看>>
华为架构师谈如何理解运用模块与微服务
查看>>
微软职位内部推荐-Senior PM
查看>>
Iterator 和 for...of 循环
查看>>
Quartz.NET simple_demo
查看>>
局部变量和参数传递的问题
查看>>
MySQL添加用户、删除用户与授权
查看>>
Django的View(视图)
查看>>
eclipse中将一个项目作为library导入另一个项目中
查看>>
node服务成长之路
查看>>
oatdata结构详解
查看>>
Objective-C入门
查看>>
整理iOS9适配中出现的坑
查看>>
单调队列优化多重背包
查看>>
HDOJ 1228 A+B(map水题)
查看>>
Object类和常用的API
查看>>
Android.对话框(AlertDialog/Toast/Snackbar)
查看>>