Python - AutoStrEnum

有一天想用 Enum 來管理整包資料的欄位,沒想到就此踏上一段追尋的旅程
One day, I would like to use Enum to manage all the fields of data.
Unexpectedly began a journey to find the answer.

打包資料

為了避免相同的 key 值以字串的形式出現在專案各個角落
所以嘗試使用 Enum 來管理相關資料的欄位

To avoid the same key of dict appearing everywhere in the project in the string form.
So I try to use Enum to manage the fields of dict.

查閱了一下資料之後,在官方文件
After studying, In the official doc,
https://docs.python.org/zh-tw/3/library/enum.html#using-automatic-values

找到了這段
I found this.

1
2
3
4
5
6
7
8
9
>>> 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()

裡面的自動化給值,看起來還蠻符合我的需求的
可以不用一個一個欄位輸入名稱就是讚

The automatic value assignment looks like matches what I need.
It’s so great that I don’t have to key the name one by one.

所以我簡單寫了一小段來看看效果
So I write a little bit of code.
Let’s see what happens.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from enum import auto, Enum


class AutoName(Enum):
def _generate_next_value_(name, start, count, last_values):
return name


class Fruit(AutoName):
BANANA = auto()
WATERMELON = auto()
DURIAN = auto()


if __name__ == '__main__':
print(Fruit.BANANA, Fruit.WATERMELON, Fruit.DURIAN)

test_dict = {
Fruit.BANANA: 2,
Fruit.DURIAN: 10,
Fruit.WATERMELON: 0
}

print(test_dict)

欸?這什麼?
What the fuck?

1
2
Fruit.BANANA Fruit.WATERMELON Fruit.DURIAN
{<Fruit.BANANA: 'BANANA'>: 2, <Fruit.DURIAN: 'DURIAN'>: 10, <Fruit.WATERMELON: 'WATERMELON'>: 0}

印出來都有 Fruit 是怎麼回事?
那個 key 怎麼長成這樣…
What’s going on with the value? Why does there always begin with Fruit?
Why does the key of dict look so ugly?

經過一番追尋之後,我發現在官方文件裡沒有我想要的答案
After more studying, I found that there is no answer I want in the official doc.

經過幾個小時的翻找官方文件還有測試之後
成功實作出了一個加強型的 Enum
After a few hours of studying and testing,
I successfully implement an extended Enum class.

先來看一下效果
Let’s take a look.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from enum import auto

from AutoStrEnum import AutoStrEnum


class Fruit(AutoStrEnum):
BANANA = auto()
WATERMELON = auto()
DURIAN = auto()


if __name__ == '__main__':
print(Fruit.BANANA, Fruit.WATERMELON, Fruit.DURIAN)

test_dict = {
Fruit.BANANA: 2,
Fruit.DURIAN: 10,
Fruit.WATERMELON: 0
}

print(test_dict)

輸出結果
Output

1
2
BANANA WATERMELON DURIAN
{BANANA: 2, DURIAN: 10, WATERMELON: 0}

完美符合我想要的效果,而且也同時具備 Enum 的所有特性
可以當作內建的 Enum 使用
This is exactly what I want, and has all the features of Enum.

程式碼在此,你也可以找到測試與所有測試過的特性
The source code is here, you can find all the tests and available features.

https://github.com/PttCodingMan/AutoStrEnum