用于检查参数类型的Pythonic方法

时间:2013-12-19 03:45:11

标签: python class exception-handling parameter-passing

我正在开展一个小方面的工作,并制作了一些课程和方法。其中一个类代表我们库存中的货架,另一个代表货架上的每个货架。我有一个方法来添加一个新的bin到架子,我添加了一些逻辑,以确保它被添加到架子之前传递一个Location对象(现在我在开发之前使用列表,然后将所有内容移动到数据库)。

但是我刚读了一本Python书,我认为处理异常通常会更好,而不是添加额外的代码。我删除了逻辑,看看我会得到什么错误,但我没有得到任何东西,它允许一个字符串代替Location对象。

是否有更多的Pythonic方法来强制执行参数的类型?

我的架子上有什么:

class CrossDock:
locations = []

def add_location(self, location):
    if isinstance(location, Location): #if this is commented out it will take what ever is passed to it
        self.locations.append(location)
    else:
        print("location parameter must be of type: Location. Parameter is of type" + str(type(location)))

我有没有办法用try / except块做到这一点?

4 个答案:

答案 0 :(得分:4)

向调用者传播异常。当他们滥用该类时,这会强制您的类用户修复无效类型。打印没有用,因为它不强制执行接口合同。

class CrossDock(object):
    def __init__(self):
        self.locations = []

    def add_location(self, location):
        if isinstance(location, Location):
            self.locations.append(location)
        else:
            raise TypeError("location must be Location, got: " +
                            repr(type(location)))

答案 1 :(得分:1)

当您尝试使用Location实例但在其中找到其他内容时,您最终可能会遇到的异常会发生在代码中的其他位置。当参数来自不可靠的源时,检查参数没有任何问题。这会将异常置于问题的根源,而不是代码中可能更难诊断的辅助位置。

您可能会做很多事情,只提出异常而不是打印错误。

def add_location(self, location):
    if not isinstance(location, Location):
        tmpl = "location parameter must be of type: Location, got %s"
        raise TypeError(tmpl % str(type(location)))
    ... do other processing here after guarding check ...

如果您无法控制调用代码,则此类检查最合适。如果您只想捕获自己编写的编程错误,可以使用断言:

def add_location(self, location):
    assert isinstance(location, Location), "location must be of type: Location"
    ... do other processing here

反对进行参数类型检查的建议旨在允许代码中的最大灵活性,例如,如果有人想要传入与位置具有相同方法的对象。检查硬编码类型会引发异常,即使代码可以正常工作。

答案 2 :(得分:1)

最pythonic的方法是不打字检查......一切都是鸭子打字。

What's the canonical way to check for type in python?

答案 3 :(得分:-2)

在try / except块

中使用assert
class Location():
    pass

class CrossDock:
    locations = []

    def add_location(self, location):
        try:
            assert(isinstance(location, Location))
            self.locations.append(location)
            print("added")
        except AssertionError:
            print("error: Parameter is of type" + str(type(location)))


c = CrossDock()
loc = Location()
c.add_location("2")
c.add_location(loc)

第一次add_location电话

会失败
location parameter must be of type: Location. Parameter is of type<type 'str'>

added