2015-08-25 16 views
6

tl; dr什麼是Pythonic(Py 3)指定大量定義的位掩碼和常量的方式?使用Enum(s)或只是有一個const的負載作爲類變量?和優點/缺點?移植C定義了Pythonic方式

背景

我移植的C代碼到Python 3.在C代碼有大量的定義被用作位掩碼:

#define ERR_1 = 0x8 
#define ERR_2 = 0x2 
#define ERR_4 = 0x100 
... 

我想在Python Pythonic的方式有這些將通過使用Enum,我碰到IntEnum這意味着我不必使用.value無處不在,就像我會用正常Enum

from enum import IntEnum 

class Errors(IntEnum): 
    BROKEN = 0x8 
    FUBARED = 0x4 
    GIVEUP = 0x7 

print(0xFF & Errors.BROKEN) 

但它仍然比只有print(0xFF & ERR_1)更詳細,如果我將它們全部作爲常量使用,我可以得到它。

+0

如果你不想讓它們變得冗長,你可以將它們命名爲'e1','e2'和'e4'(用C代碼)並將它們用作'Errors.e2'。無論如何,我認爲枚舉是要走的路,而且總是很好(特別是如果你打算增長/維護軟件的話)。 –

回答

1

我認爲使用enum更pythonic - 有很多努力創建該模塊,並不是沒有理由。

事情的「標準」方式是使用常量(如ERR_1),但這是醜陋的,越野車,真的很難保守。這就是爲什麼這個模塊是開發的。

現在,我已經說平淡的回答,我也建議你同時使用兩種:

ERR_1 = 0x8 
ERR_2 = 0x4 
ERR_3 = 0x7 

class Errors(IntEnum): 
    BROKEN = ERR_1 
    FUBARED = ERR_2 
    GIVEUP = ERR_3 

print(0xFF & Errors.BROKEN) 
print(0xFF & ERR_1) 

我認爲這是醜陋的,但你兩個選擇之間徘徊,所以我想告訴你如何讓他們成爲一體。

另外值得一讀:

2

這一切都取決於。

如果常量是邏輯上的整數(你做算術運算,按位邏輯等等),它們應該是常規的全局變量。標誌值落在這裏,就像os.open()的各種標誌一樣,但是如果你只是指定一個常數來指示要執行哪個操作,則枚舉更合適(或更好的是,多驅動程序功能)。

枚舉類型通常在您有一組(相對)較小的值時使用,並且這些值通常只能彼此比較(例如使用if x is MyEnum.FIRST... elif x is MyEnum.SECOND等)。在這種情況下,您通常不需要IntEnum,因爲您經常不應該首先使用.value。的確,IntEnum大部分是向後兼容的黑客。

0

我不認爲有任何理由讓他們成爲班級的一部分。

errors模塊

# errors.py 
BROKEN = 0x8 
FUBARED = 0x4 
GIVEUP = 0x7 

main模塊

import errors 

print(0xFF & errors.BROKEN) 
1

使用的Enum肯定是要走的路,你甚至可以在模塊範圍的枚舉成員很容易:

class Errors(IntEnum): 
    BROKEN = 0x8 
    FUBARED = 0x4 
    GIVEUP = 0x7 
globals().update(Errors.__members__) 

so your co mparison變爲:

print(0xFF & BROKEN) 

關於它有道理不使用Enum唯一的一次是當你有幾個名字是不是真的,但重複映射到相同的值,因爲重複值將全部映射到相同名稱:

class Bad(Enum): 
    BROKEN = 0x01 
    MISSING = 0x01 
    BLUE = 0x01 

但是,如果你有獨特的價值Enum不同的名稱是要走的路。