我知道基类Enum
和IntEnum
。两者都非常有用,但是我错过了标志操作的功能。我不希望这两个类实现我希望的功能。
让我们构造一个示例:
class NetlistKind(IntEnum):
Unknown = 0
LatticeNetlist = 1
QuartusNetlist = 2
XSTNetlist = 4
CoreGenNetlist = 8
All = 15
如您所见,我已经在使用
IntEnum
来获取该枚举的算术功能。最好使用@unique
这样的东西来确保所有值都是2的幂。我可以通过 fork enum.unique来实现此目的。 (我知道All
是该规则的异常(exception)。)如何使用这样的枚举?
filter = NetlistKind.LatticeNetlist | NetlistKind.QuartusNetlist
由于采用了底层int位,因此可以进行位操作,并且filter的内部值为3。
如果有一个“在过滤器Y中设置X标记”功能,或者甚至是一个更好的运算符,将是一个很好的选择。我为
x in y
添加了一个魔术函数:@unique
class NetlistKind(IntEnum):
Unknown = 0
LatticeNetlist = 1
QuartusNetlist = 2
XSTNetlist = 4
CoreGenNetlist = 8
All = 15
def __contains__(self, item):
return (self.value & item.value) == item.value
用法示例:
....
def GetNetlists(self, filter=NetlistKind.All):
for entity in self._entities:
for nl in entity.GetNetlists():
if (nl.kind in filter):
yield nl
def GetXilinxNetlists(self):
return self.GetNetlists(NetlistKind.XSTNetlist | NetlistKind.CoreGenNetlist)
所以问题是:
开放功能:
__str__
中所有 Activity 标志的列表最佳答案
我最近发布了针对此问题的开源软件包py-flags。该库正是具有此功能,并且其设计在很大程度上受到python3枚举模块的影响。
关于它是否足以实现这样的flags类存在争议,因为它的功能与该语言提供的其他方法( bool(boolean) 变量,集合,具有 bool(boolean) 属性的对象或带有 bool(boolean) 项的字典等的功能)有很大的重叠。 。因此,我觉得flags类的用途太狭窄和/或多余,以致无法进入标准库,但是在某些情况下,它比以前列出的解决方案好得多,因此可以使用“pip install”库派上用场。
使用py-flags模块,您的示例如下所示:
from flags import Flags
class NetlistKind(Flags):
Unknown = 0
LatticeNetlist = 1
QuartusNetlist = 2
XSTNetlist = 4
CoreGenNetlist = 8
All = 15
由于通过库声明的标志类会自动提供两个“虚拟”标志:
NetlistKind.no_flags
和NetlistKind.all_flags
,因此上述操作可能需要进一步调整。这些使已经声明的NetlistKind.Unknown
和NetlistKind.All
变得多余,因此我们可以将它们从声明中删除,但是问题是no_flags
和all_flags
与您的命名约定不匹配。为此,我们在您的项目中声明一个flags基类,而不是flags.Flags
,您将不得不在项目的其余部分中使用它:from flags import Flags
class BaseFlags(Flags):
__no_flags_name__ = 'Unknown'
__all_flags_name__ = 'All'
基于先前声明的基类,该基类可以被您项目中的任何标志所继承,我们可以将标志声明更改为:
class NetlistKind(BaseFlags):
LatticeNetlist = 1
QuartusNetlist = 2
XSTNetlist = 4
CoreGenNetlist = 8
这样,
NetlistKind.Unknown
会自动声明为零。 NetlistKind.All
也在那里,它自动是所有已声明标志的组合。可以使用/不使用这些虚拟标志来迭代枚举成员。您还可以声明别名(与另一个先前声明的标志具有相同值的标志)。作为使用“函数调用样式”的替代声明(也由标准枚举模块提供):
NetlistKind = BaseFlags('NetlistKind', ['LatticeNetlist', 'QuartusNetlist',
'XSTNetlist', 'CoreGenNetlist'])
如果标志类声明了一些成员,则将其视为最终成员。尝试对其进行子类化将导致错误。从语义上讲,为了添加新成员或更改功能,不允许子类化flag类。
除此之外,flags类还以类型安全的方式向您提供列出的运算符( bool(boolean) 运算符,in,迭代等)。在接下来的几天中,我将完成README.rst并在包接口(interface)上进行一些设置,但是基本功能已经存在并且已经进行了很好的测试。
关于python-3.x - 是否有用于标记/位掩码操作的Python类/枚举?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36829820/