在 Python 中验证方法参数的对象类型的最佳方法是什么?

What is the optimal approach for validating object types of method arguments in Python?

这不是代码的特定问题,而是一个开放的概念性问题,所以我希望它在正确的地方。

我有一个 pandas 数据框,我经常对边界时间和其他可选变量(这里是频率)的数据进行子集化。频率具有离散值,因此我可以 select 来自单个或多个通道的数据。我的函数看起来像这样:

def subset_data(data, times, freq=None):

    sub_data = data.loc[data['time'].between(*times), :]

    if freq is not None:
   
        if isinstance(freq, int):

            sub_data = sub_data.loc[sub_data['frequency'] == freq, :]

        elif isinstance(freq, tuple):

            sub_data = sub_data.loc[sub_data['frequency'].between(*freq), :]
                
    return sub_data

我想将第二个条件修改为对任何数字类型进行更一般的检查,我发现了这个问题 - What is the most pythonic way to check if an object is a number?。接受的答案让我质疑我在这里的方法及其总体有效性。最后一点,特别是:

If you are more concerned about how an object acts rather than what it is, perform your operations as if you have a number and use exceptions to tell you otherwise.

我认为这是在暗示我应该做这样的事情

def subset_data(data, times, freq=None):

    sub_data = data.loc[data['time'].between(*times), :]

    if freq is not None:

        try:
   
            if isinstance(freq, tuple):

                sub_data = sub_data.loc[sub_data['frequency'].between(*freq), :]
       
            elif isinstance(freq, int):

                sub_data = sub_data.loc[sub_data['frequency'] == freq, :]

        except TypeError:

            print('sub_data filtered on time only. freq must be numeric.')

    return sub_data

if isinstance(freq, tuple):

    sub_data = sub_data.loc[sub_data['frequency'].between(*freq), :]
       
elif isinstance(freq, int):

    sub_data = sub_data.loc[sub_data['frequency'] == freq, :]

else:

    raise TypeError('freq must be tuple or numeric')

但有兴趣知道这是否接近共识。

原版也缺少一些完整性验证 - 我懒得在自己的代码中编写它,如果我假设我将是唯一一个使用它并且有一个类型的先验知识。如果不是这种情况,我会包括:

if isinstance(freq, int):

    sub_data = sub_data.loc[sub_data['frequency'] == freq, :]

elif isinstance(freq, tuple) and len(freq) == 2:

    if isinstance(freq[0], int) and isinstance(freq[1], int):

        sub_data = sub_data.loc[sub_data['frequency'].between(*freq), :]

显式检查对象类型和属性的做法以及这种一般验证方法是否适用于 Python,还是我的知识有所欠缺?也许一切都可以写得更简洁,但我遗漏了一些东西。 post 从技术上讲有两个问题,但我希望总体的总体概念足够清晰,对其他人有用并允许一些答案。

如果我没记错的话,使用 try/except 的第二种方法,如果传入的类型不正确,您只会看到 TypeError:... 而不是真正的详细说明正是导致代码中的问题。话虽如此,第一种方法是通过检查 inttuple 这两个很好的条件来强化检查过程。我不会有偏好,但是这两种方法对我来说都很好,尽管如果 Exception 子句你可以让它更详细以获得特定的错误日志(如果有的话)。

理解 Exceptions 的一个很好的例子,如果你想在尝试访问不存在的字典中的元素或值时查看 KeyError 的例子,然后print(e) #e is the error from KeyError exception being raised。希望这有所帮助。干杯。