python - 如何在没有强类型的情况下确保可靠的合约?

标签 python python-2.7 types duck-typing dynamic-typing

get_min_length() 采用的参数必须与 get_pkt_type() 的可能返回值相匹配:

def get_pkt_type(some_val):
    """Determine the type of an XCP packet.

    :return:
        'CMD' if "Command" packet,
        'RES' if "Command Response" packet,
        'ERR' if "Error" packet,
        'CMD/RES' if uncertain whether a CONNECT CMD or a
            RES packet, as their frame bytes can look identical.
    :rtype: str
    """
    if something:
        return 'CMD'
    elif something_else2:
        return 'RES'
    elif something_else3:
        return 'ERR'
    elif something_else4:
        return 'CMD/RES'

def get_min_length(packet_type):
    if packet_type in ['CMD', 'RES']:
        return 4
    elif packet_type in ['ERR', 'CMD/RES']:
        return 6

packet_type = get_pkt_type(some_val)
length = get_min_length(packet_type)

如果程序员向 get_pkt_type() 添加新的数据包类型返回值,我如何确保他也不会忘记将该值添加到 get_min_length()。在强类型语言中,packet_type 将是返回和传递的已定义类型,因此这样我就具有安全性。

最佳答案

通常,在 Python 中,如果您有一组可扩展的值,则创建浅层继承层次结构是有意义的。这样比较不容易忘记。枚举更适合固定值集。

也就是说,你应该做的第一件事是尾随

raise ValueError("Unexpected enum value")

您的职能。

您可能考虑的另一件事是使用字典来表示此类映射:

pkt_lengths = {
    'CMD': 4,
    'RES': 4,
    'ERR': 6,
    'CMD/RES': 6,
}

get_min_length = pkt_lengths.__getitem__

然后您可以添加一个简单的测试

packet_types = {'CMD', 'RES', 'ERR', 'CMD/RES'}
assert not packet_types.symmetric_difference(pkt_lengths)

如果您经常这样做,请构建一个函数:

def enum_mapper(enum, mapper):
    assert not enum.symmetric_difference(mapper)
    return mapper.__getitem__

这可以让你做到

get_min_length = enum_mapper(packet_types, pkt_lengths)

并在启动时进行检查。

此外,请考虑使用适当的enum.Enum

关于python - 如何在没有强类型的情况下确保可靠的合约?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32756179/

相关文章:

Python 双向映射

python - 条形图中令人讨厌的空白(matplotlib,Python)

Python argparse 使用 switch 来运行 if 语句

google-app-engine - 处理 appengine 中的子域

collections - 我怎样才能拥有一组因关联类型不同而不同的对象?

ios - 将自定义图标字形附加到 NSAttributedString

Python 可以打开文件,PL/Python 不能

python - django.core.exceptions.AppRegistryNotReady : Apps aren't loaded yet. (django 2.0.1)(Python 3.6)

python - 我们如何从Python中的glyph id获取unicode?

c - 为什么我们不用一个短整型来表示一个返回值呢?