我已经生成了一个具有不同数据类型的IntEnum
class DataTypes(IntEnum):
Bytei = 0 # RAM buffer variable 8 bit (on-off input)
Byteo = 1 # RAM buffer variable 8 bit (on-off output)
Bytem = 2 # RAM buffer variable 8 bit (flag)
Wordi = 3 # RAM system variable 16 bit (signed int)
Wordo = 4 # RAM system variable 16 bit (signed int)
Wordm = 5 # RAM buffer variable 16 bit (signed int)
Wordp = 6 # E2PROM variable (parameter) 16 bit (signed int)
Dworm = 7 # RAM buffer variable 32 bit (signed long int)
Dworp = 8 # E2PROM variable (parameter) 32 bit (signed long int)
枚举的整数被指定用于通信,所以我想保持这个枚举,因为它或者至少类似的具有相同关联的东西。
在注释中可见数据类型具有不同的大小我想在某种程度上获得数据类型的大小。我可以编写一个函数来映射参数
def map_types(DataType):
if not 0 <= DataType <=8 :
size = 0
elif DataType <3:
size = 1
elif DataType <7:
size = 2
else:
size = 4
return size
但是有一种漂亮,更清洁和/或更多的pythonic方式吗?
答案 0 :(得分:2)
您希望在size
枚举上有一个额外的DataType
属性(也可能是__doc__
)。您可以自己滚动(如果使用stdlib或enum34
backport,或者利用aenum
的高级功能 1 。
使用enum34
(py2 / 3)或stdlib enum
(3.4 +)滚动自己:
from enum import IntEnum
class DataTypes(IntEnum):
def __new__(cls, value, size, doc):
obj = int.__new__(cls)
obj._value_ = value
return obj
def __init__(self, value, size, doc):
# value already handled, ignore it
self.size = size
self.__doc__ = doc
Bytei = 0, 8, 'RAM buffer variable (on-off input)'
Byteo = 1, 8, 'RAM buffer variable (on-off output)'
Bytem = 2, 8, 'RAM buffer variable (flag)'
Wordi = 3, 16, 'RAM system variable (signed int)'
Wordo = 4, 16, 'RAM system variable (signed int)'
Wordm = 5, 16, 'RAM buffer variable (signed int)'
Wordp = 6, 16, 'E2PROM variable (parameter) (signed int)'
Dworm = 7, 32, 'RAM buffer variable (signed long int)'
Dworp = 8, 32, 'E2PROM variable (parameter) (signed long int)'
利用aenum
的功能(py2 / 3):
from aenum import IntEnum
class DataTypes(IntEnum):
_init_ = 'value size __doc__'
Bytei = 0, 8, 'RAM buffer variable (on-off input)'
Byteo = 1, 8, 'RAM buffer variable (on-off output)'
Bytem = 2, 8, 'RAM buffer variable (flag)'
Wordi = 3, 16, 'RAM system variable (signed int)'
Wordo = 4, 16, 'RAM system variable (signed int)'
Wordm = 5, 16, 'RAM buffer variable (signed int)'
Wordp = 6, 16, 'E2PROM variable (parameter) (signed int)'
Dworm = 7, 32, 'RAM buffer variable (signed long int)'
Dworp = 8, 32, 'E2PROM variable (parameter) (signed long int)'
并在使用中:
--> print repr(DataTypes.Bytei)
<DataTypes.Bytei: 0>
--> print DataTypes.Bytei
DataTypes.Bytei
--> print DataTypes.Bytei.size
8
--> print DataTypes.Bytei.__doc__
RAM buffer variable (on-off input)
1 披露:我是Python stdlib Enum
,enum34
backport和Advanced Enumeration (aenum
)图书馆的作者。
答案 1 :(得分:1)
稍微更简洁的方法是将函数移动到类中。
class DataTypes(IntEnum):
Bytei = 0 # RAM buffer variable 8 bit (on-off input)
Byteo = 1 # RAM buffer variable 8 bit (on-off output)
Bytem = 2 # RAM buffer variable 8 bit (flag)
Wordi = 3 # RAM system variable 16 bit (signed int)
Wordo = 4 # RAM system variable 16 bit (signed int)
Wordm = 5 # RAM buffer variable 16 bit (signed int)
Wordp = 6 # E2PROM variable (parameter) 16 bit (signed int)
Dworm = 7 # RAM buffer variable 32 bit (signed long int)
Dworp = 8 # E2PROM variable (parameter) 32 bit (signed long int)
@property
def size(self): # You could also link it to the name. If self.name.startswith('Byte') ...
if self.value < 3:
return 1
elif self.value < 7:
return 2
else:
return 4
def __repr__(self):
old_repr = super(DataTypes, self).__repr__()
return old_repr.replace('>', ', size: {}>'.format(self.size))
for thing in DataTypes:
print(repr(thing), thing.value, thing.size, 2 < thing, thing < 2, sep=' | ')
输出:
<DataTypes.Bytei: 0, size: 1> | 0 | 1 | False | True
<DataTypes.Byteo: 1, size: 1> | 1 | 1 | False | True
<DataTypes.Bytem: 2, size: 1> | 2 | 1 | False | False
<DataTypes.Wordi: 3, size: 2> | 3 | 2 | True | False
<DataTypes.Wordo: 4, size: 2> | 4 | 2 | True | False
<DataTypes.Wordm: 5, size: 2> | 5 | 2 | True | False
<DataTypes.Wordp: 6, size: 2> | 6 | 2 | True | False
<DataTypes.Dworm: 7, size: 4> | 7 | 4 | True | False
<DataTypes.Dworp: 8, size: 4> | 8 | 4 | True | False
@property
装饰器使方法看起来像一个属性。没有装饰器,为了获得你会调用DataTypes.Bytei.size()
的大小。装饰器DataTypes.Bytie.size
返回同样的东西。所以@property
在这里是不必要的,但我认为,因为它的作用就像是对象的属性而不是方法,所以让它像上面一样工作会很好。
super
调用父类的方法。因此,super(DataTypes, self).__repr__()
表示使用repr
获取self
并使用父类中的repr
函数(这会返回一个字符串)。然后,因为它是str
,实际上是str.replace
。