2

说明

我读过很多关于在 python 中检查值类型的意见,大多数人说你不应该检查类型,而是使用 try 和 except。我想澄清几件事。

问题

当我有这样的方法时:

def set_age(self, age):
    self._age = age

我不能让用户传递除 int 以外的任何类型,因为稍后在代码中它可能会导致一些更难调试的错误。根据 Python 方法,我无法检查类型。那么我应该如何以正确的方式尝试呢?

def set_age(self, age):
    try:
        age = int(age)
    except TypeError:
        raise TypeError('First parameter must be of int type.')
    self._age = age

要不就

def set_age(self, age):
    self._age = int(age)

并让 Python 自行引发错误。

我知道这可能是愚蠢的问题,我只是想确定一下。

4

2 回答 2

2

如果它不是整数,Python 将引发适当的错误,因此无需将您自己的错误置于其顶部。

不过,让我们退后一步,因为这里还有其他问题。getter 和 setter 真的是 unpythonic - 要么只使用属性,要么使用属性

在这种情况下,我认为您仍然在以错误的方式思考。我们不在 Python 中进行类型检查的原因是因为我们不应该关心某个东西是什么类型,只要它在给定的情况下可以工作。让所有东西都成为你认为应该的类型,本质上是类型检查。

你说它会使调试变得更加困难,但这并不是大多数人真正拥有的经验。鸭子打字旨在让任何可以完成这项工作的东西都能完成这项工作。将一切都转换为int限制您的程序。问题不在这里,问题在于您的代码传递了一些对您的类没有意义的东西。以我的经验,这实际上是一件非常罕见的事情——你不会倾向于在课堂上随意扔东西,看看有什么效果。

所以,我在这里的建议是你使用一个属性——只是做x.age = ...而不是使用set_age()或类似的东西。如果你真的需要一个int(比如,只有整数才有意义),那么使用一个属性并int()在 setter 中调用,如果发生错误,则将错误传播给调用者。

于 2013-01-26T14:41:49.267 回答
1

python 的一个信条是“请求宽恕胜于许可”。很多时候,你的函数调用所产生的异常足以告诉你的函数的调用者出了什么问题。

话虽如此,在某些情况下,我会抛出一个更具体的异常,其中调用者的语义并不完全一致。我能想到的一个例子是我正在检查一个 json 响应并且我在字典的一个元素上得到一个“关键错误”。这通常意味着我发出的任何请求都失败了,因此我找不到我需要的数据。反过来,我会根据我的功能(例如“查询失败”)在语义上抛出一些东西。

大多数时候,虽然被调用函数“类型错误”或“io 错误”抛出的异常对我的函数调用者来说应该是完全有意义的,所以我不必费心去捕捉和重新抛出。

于 2013-01-26T14:43:57.893 回答