2017-10-10 52 views
2

我觀察到我可以將某些整數值轉換爲它們的標誌分解類型,並且我可以將標誌字符串名稱轉換爲標誌,但是我還沒有弄清楚是否有方法將標誌名稱的字符串聯合到enum.Flag有沒有辦法將表示多個標誌成員的字符串轉換爲組合enum.Flag?

import enum 
flag = enum.Flag('flg' , ['a', 'b', 'c', 'd']) 

# Valid 1:1 conversions... 
>>> flag["a"] 
<flg.a: 1> 
>>> flag["b"] 
<flg.b: 2> 
>>> flag(1) 
<flg.a: 1> 
>>> flag(2) 
<flg.b: 2> 

# Valid union int conversion 
>>> flag(7) 
<flg.c|b|a: 7> 
>>> flag(15) # largest integer flag can represent (1+2+4+8) 
<flg.d|c|b|a: 15> 

# Out of bounds 
>>> flag(16) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "C:\Anaconda3\lib\enum.py", line 291, in __call__ 
    return cls.__new__(cls, value) 
    File "C:\Anaconda3\lib\enum.py", line 533, in __new__ 
    return cls._missing_(value) 
    File "C:\Anaconda3\lib\enum.py", line 673, in _missing_ 
    possible_member = cls._create_pseudo_member_(value) 
    File "C:\Anaconda3\lib\enum.py", line 688, in _create_pseudo_member_ 
    raise ValueError("%r is not a valid %s" % (value, cls.__name__)) 
ValueError: 16 is not a valid flg 

我希望我也許能拉過東西的 flag["d|c|b|a"]精神,但作爲一個字典這種轉換隻適用於不同的標誌成員名稱,而不是其中的任何聚集。與此同時,我正在手動進行拆分,轉換,聯合合併,但我很好奇是否存在像int轉換情況那樣的更直接的路由。

編輯: 縱觀源enum.py,它出現在正確的術語是不是工會,但複合

# enum.py 
def _create_pseudo_member_(cls, value): 
    """ 
    Create a composite member iff value contains only members. 
    """ 

回答

2

你可以繼承enum.Flag和攔截其_missing_()方法:

from functools import reduce 

import enum 


class UnionFlag(enum.Flag): 

    @classmethod 
    def _missing_(cls, value): 
     if isinstance(value, str): 
      return reduce(cls.__or__, (cls[s] for s in value.split('|'))) 
     else: 
      return super()._missing_(value) 

>>> flag = UnionFlag('uflg', ['a', 'b', 'c', 'd']) 
>>> flag.a 
<uflg.a: 1> 
>>> flag(3) 
<uflg.b|a: 3> 
>>> flag['c'] 
<uflg.c: 4> 
>>> flag('a|b|d') 
<uflg.d|b|a: 11> 
相關問題