在 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:...
而不是真正的详细说明正是导致代码中的问题。话虽如此,第一种方法是通过检查 int
和 tuple
这两个很好的条件来强化检查过程。我不会有偏好,但是这两种方法对我来说都很好,尽管如果 Exception
子句你可以让它更详细以获得特定的错误日志(如果有的话)。
理解 Exceptions
的一个很好的例子,如果你想在尝试访问不存在的字典中的元素或值时查看 KeyError
的例子,然后print(e) #e is the error from KeyError exception being raised
。希望这有所帮助。干杯。
这不是代码的特定问题,而是一个开放的概念性问题,所以我希望它在正确的地方。
我有一个 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:...
而不是真正的详细说明正是导致代码中的问题。话虽如此,第一种方法是通过检查 int
和 tuple
这两个很好的条件来强化检查过程。我不会有偏好,但是这两种方法对我来说都很好,尽管如果 Exception
子句你可以让它更详细以获得特定的错误日志(如果有的话)。
理解 Exceptions
的一个很好的例子,如果你想在尝试访问不存在的字典中的元素或值时查看 KeyError
的例子,然后print(e) #e is the error from KeyError exception being raised
。希望这有所帮助。干杯。