2

在我最近的项目中,我遇到了一个问题,即某些价值观经常被误解。例如,我将一个波计算为两个波的总和(为此我需要两个幅度和两个相移),然后在 4 个点对其进行采样。我将这些四个值的元组传递给不同的函数,但有时我会错误地传递波参数而不是样本点。

这些错误很难找到,因为所有计算都没有任何错误,但是在这种情况下这些值完全没有意义,所以结果就是错误的。

我现在想要的是某种语义类型。我想声明一个函数返回样本点,而另一个函数等待样本点,并且我不能做任何会与此声明冲突而不会立即出错的事情。

有没有办法在python中做到这一点?

4

2 回答 2

5

我建议实现特定的数据类型,以便能够区分具有相同结构的不同类型的信息。例如,您可以简单地进行子类list化,然后在运行时在您的函数中进行一些类型检查:

class WaveParameter(list):
    pass

class Point(list):
    pass

# you can use them just like lists    
point = Point([1, 2, 3, 4])

wp = WaveParameter([5, 6])

# of course all methods from list are inherited
wp.append(7)
wp.append(8)

# let's check them
print(point)
print(wp)

# type checking examples
print isinstance(point, Point)
print isinstance(wp, Point)
print isinstance(point, WaveParameter)
print isinstance(wp, WaveParameter)

因此,您可以在函数中包含这种类型检查,以确保将正确类型的数据传递给它:

def example_function_with_waveparameter(data):
    if not isinstance(data, WaveParameter):
        log.error("received wrong parameter type (%s instead WaveParameter)" %
                  type(data))
    # and then do the stuff

或者简单地说assert

def example_function_with_waveparameter(data):
    assert(isinstance(data, WaveParameter))
于 2013-09-30T07:53:17.627 回答
2

Pyhon 的“语义类型”概念称为 a class,但如前所述,Python 是动态类型的,因此即使使用自定义类而不是元组,您也不会收到任何编译时错误 - 如果您的类充其量您会收到运行时错误被设计成试图使用一个而不是另一个会失败。

现在类不仅与数据有关,它们也与行为有关,因此,如果您有执行特定波形计算的函数,这些函数可能会成为Waveform该类的方法,并且同上Point,这可能足以避免逻辑错误就像将“波形”元组传递给期望“点”元组的函数。

长话短说:如果你想要一种静态类型的函数式语言,Python 不是正确的工具(Haskell 可能是更好的选择)。如果您真的想要/必须使用 Python,请尝试使用类和方法而不是元组和函数,它仍然不会在编译时检测到类型错误,但您可能会遇到更少的类型错误并且这些类型错误将是在运行时检测到,而不是产生错误的结果。

于 2013-09-30T10:01:48.943 回答