我想在python中創建一個枚舉。我見過幾種解決方案(@alec thomas的第二個回答here對我最感興趣),但是我想讓這個枚舉成爲不變的。我發現一個不可變的python recipe,但我想要一個類似字典的鍵/值關聯。在python中使用duck-punching的不可變枚舉
我試圖使用鴨子衝孔來增加屬性,如果您試圖在該屬性上調用fset
或fdel
,該屬性將拋出AttributeError
。
我遇到了麻煩,定義了屬性的fget
函數。下面的代碼我到目前爲止:
def enum(*sequential, **named):
# Build property dict
enums = dict(zip(sequential, range(len(sequential))), **named)
# Define an errorhandler function
def err_func(*args, **kwargs):
raise AttributeError('Enumeration is immutable!')
# Create a base type
t = type('enum', (object,), {})
# Add properties to class by duck-punching
for attr, val in enums.iteritems():
setattr(t, attr, property(lambda attr: enums[attr], err_func, err_func))
# Return an instance of the new class
return t()
e = enum('OK', 'CANCEL', 'QUIT')
print e
print e.OK
print e.CANCEL
print e.QUIT
# Immutable?
e.OK = 'ASDF' # Does throw the correct exception
print e.OK
從這個輸出是:
<__main__.enum object at 0x01FC8F70>
Traceback (most recent call last):
File "enum.py", line 24, in <module>
print e.OK
File "enum.py", line 17, in <lambda>
setattr(t, attr, property(lambda attr: enums[attr], err_func, err_func))
KeyError: <__main__.enum object at 0x01FC8F70>
也許這是不是創建一個枚舉的最佳方式,但它的短,我想探索更多的這整個鴨子打孔/猴子修補的概念。
謝謝刪除或修改!最終的解決方案如下所示:'def getter(cls,val):return lambda cls:val'。這些屬性是這樣插入的:'setattr(t,attr,property(getter(t,val),err_func,err_func))' – Josh