我打算实现一个包含大量常量的库。现在已经有很多关于堆栈溢出上的常量的问题了。但是,我在思考一个使事情复杂化的特殊情况,我不知道该走哪条路。可能已经有人解决了类似的问题,可以帮助我避免明显的失败:)。
更准确地说,我将实现SMPP (短消息p2p)相关的内容。SMPP由许多具有不同可能值的字段组成,这些字段有时由不同的部分组成。例如,esm_class字段是一个8位整数,位1-0、5-2和7-6是“子字段”。因此,值esm_class由三个常量“串联”在一起。
但故事还在继续。esm_class子字段有不同的含义,这取决于它们在其中使用的消息类型。
现在出现了几个问题:
对于问题3,我选择了tupels: CONST_NAME = (0x01,'value E足意‘)。
我对其他问题的第一个想法是将常量组织在模块中。例如,这将使我们:
对于data_coding来说,这很好。但是esm_class实际上是由‘子字段’组成的。所以我想:
这已经相当长了,例如,导致了constants.esm_class.features.UDHI_AND_REPLAY_PATH。不太好,不知怎么的。这还不是我所需要的..。实际上,我甚至需要将constants.esm_class.types分开,因为类型值在不同的上下文中有不同的含义(基本上是传入消息与传出短消息)。因此,如果我遵循模式: constants.esm_class.types.outgoing和constants.esm_class.types.incoming,就会产生更多的子模块。
此外,我还需要一种将类型、模式和特性连接起来以创建esm_class值的方法,还需要将esm_class拆分为两个部分进行解析。因此,需要有一种从常量构建字段值的通用方法,还需要检测某个值是非法的(即具有一个未由常量定义的值)。
我的问题是:你认为我应该遵循的最佳方式是什么?我应该去上课吗?正如我所读到的python的最佳实践一样,在模块级别上定义常量。我还看到了使用类的一些问题。所以,可能每一个可能的字段都会有一个新的数据类型来完成这个任务?我被困住了,期待着你的想法!
编辑:--我打算在 3.3+中使用这个库,可能我想使它与2.7兼容,因此不幸的是,Python3.4中的Enum不是解决方案。
编辑2:可能用太少的文字包装了太多的信息。所以我会举一个例子。
SMPP中的esm_class是一种派生值,由类型、模式和特性组成。例如,如果esm_class的值为00111100,实际上它意味着该特性等于00,模式为1111,类型再次为00。这就是我所说的“子类型”。这些常量将与按位操作放在一起。
发布于 2014-07-25 15:58:30
我会尽力给出答案(我希望我对你的理解是正确的)。在阐述我的上述评论时,我想说的是:
class esm_class:
BITMASK_FEATURE = 0b11000000
BITMASK_MODE = 0b00111100
BITMASK_TYPE = 0b00000011
class Features:
FEATURE_1 = 0b00
FEATURE_2 = 0b01
FEATURE_3 = 0b10
FEATURE_4 = 0b11
class Modes:
MODE_1 = 0b0000
# …
class Types:
TYPE_1 = 0b00
TYPE_2 = 0b01
# …
def __init__(self, type_, mode, feature):
self.type = type_
self.mode = mode
self.feature = feature
def __bytes__(self):
'''
Use this to write an instance of esm_class to a file-like
object or stream, e.g..:
mysocket.send(bytes(my_esm_class_obj))
'''
return ((self.feature << 6) | (self.mode << 2) |
self.type).to_bytes(1, byteorder='big')
@classmethod
def parse(cls, filelike):
'''
Use this to parse incoming data from a file-like object
and create an instance of esm_class accordingly, e.g:
my_esm_class_obj = esm_class.parse(stream)
'''
instance = cls()
data = filelike.read(1)
instance.feature = int.from_bytes((data & cls.BITMASK_FEATURE) >> 6)
instance.mode = int.from_bytes((data & cls.BITMASK_MODE) >> 2)
instance.mode = int.from_bytes((data & cls.BITMASK_TYPE) >> 2)现在,可以对代码进行优化,但重点是:我试图尽快抽象出二进制表示,以便达到表示协议中出现的结构的类层次结构。因此,我没有简单地将常量/值放在不同的模块中,而是以这样的方式组织它们,使它们与它们所属的结构一起出现--这也是您将在代码的其余部分中使用的结构。
还有一些需要注意的事项:
Features、Modes和Types,并将所有值放在esm_class的范围内。但是,只有当符号的名称FEATURE_1、MODE_2等说明它们对应的位串的哪一部分(即特征部分或模式部分或…)时,我才会这样做。。value属性)时,处理它们很繁琐,但这也是因为我不需要符号名称本身。你的里程可能会不同。https://stackoverflow.com/questions/24957795
复制相似问题