【问题标题】:What is the optimal approach for validating object types of method arguments in Python?在 Python 中验证方法参数的对象类型的最佳方法是什么?
【发布时间】:2020-10-30 16:07:25
【问题描述】:

这不是代码的具体问题,而是一个开放的概念性问题,所以我希望它出现在正确的位置。

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

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?。接受的答案让我质疑我在这里的方法及其总体有效性。最后一点,特别是:

如果您更关心对象的行为方式而不是它是什么,请像有一个数字一样执行您的操作,并使用异常来告诉您其他情况。

我将此解释为暗示我应该做这样的事情

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,或者我的知识在某处缺乏?也许一切都可以写得更简洁,我错过了一些东西。从技术上讲,这篇博文中有两个问题,但我希望总体概念足够清晰,对其他人有用并提供一些答案。

【问题讨论】:

    标签: python pandas validation conceptual


    【解决方案1】:

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

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

    【讨论】:

    • 感谢您的回答以及进一步了解的指针。我认为我的问题之一是不愿意为附加条件牺牲空间。我可以(并且可能应该)包括许多其他验证步骤,例如检查通过的频率(在单一情况下)是否实际上是离散通道之一,因此它会添加很多行!跨度>
    • 为了帮助您更多,我会先检查关键组件,即使存在与类型检查或语法问题相关的错误,您也不会遇到解决问题几行之内。这是一个很好的 SO link,第三个答案在逐步完成 try/excepts 和条件处理方面做得很好。
    • 再次感谢。已经有几天了,但您介意评论一下我在编辑中包含的第三个示例吗?不知道你是否一开始就看到了,但我会倾向于这样做
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    • 2018-04-26
    • 2016-07-27
    • 2015-08-08
    相关资源
    最近更新 更多