Pythonic方式比较不受信任的简单参数

时间:2012-06-25 17:25:17

标签: types compare python trusted-vs-untrusted

我得到的基本理念是不要求许可,只要这样做并请求宽恕。例如,它不需要是一个具有.read()方法的文件,当您想要读取类似文件的对象时,当您发现“正常工作”时,您会感谢自己。但是,对于像文件这样的复杂对象而言,这比使用数字等简单对象更容易理解。

所以我正在尝试写一个非常简单的类。细节无关紧要,但它有一个内部计数器,当计数器超出限制时必须做一些事情。创建对象时,该限制作为参数提供。

现在我在考虑防御性编程。显然我希望我的限制是一个整数,或者至少比较整数的东西。它可能比那弱,因为如果它是一个浮点数,我做的> =测试仍会提供正确的行为。

虽然类用户会知道这个参数应该是一个整数,但我希望这个对象做一些不足为奇的事情。我的第一个想法是检查我确实有一个数字

if isinstance(limit,(int,long,float)):

但是这里有任何数量的“不要测试,尝试除了”答案,所以我知道这是unpythonic。最好使用限制,并等待抛出异常。所以我尝试了这个:除了各种类型的限制

if counter >= limit:

如果limit是int或float,这可以正常工作。然后我限制了一个字符串或一个元组,与数字进行比较的对象没有任何明显或合理的定义,并等待捕获异常。但它执行,返回一个布尔值,并保持沉默。

所以我是RTFM,结果是compare不会引发混合类型的异常,这与“容器中的x”的操作有关,对于任意类型测试相等性。对于不同的类型,它总是返回not_equal,但是一致的,幅度比较是任意的。如果混合类型的幅度比较总是返回False,我也许可以使用它,但它也会愉快地返回True。

如果我尝试在非数字上使用其他类似整数的行为,我会得到预期的异常,例如此字符串+数字会引发TypeError

limit+0

所以我可以说

if counter >= (limit+0)

如果limit不是数字,则抛出所需的异常。但这感觉几乎混淆了。我正在做一些额外的表达,以便通过后门进行类型测试。任何代码优化器或其他编辑器都会删除明显冗余的算术运算。这就像看到物体是否像鸭子一样重,看它是否由木头制成,因此可以像女巫一样被烧掉(等等)。

更明确的可能性是

if counter >= int(limit)

至少内置了一些解释。它并不完全符合我想要在任何情况下发生的事情,但它现在已经足够了,并且它不会让任何人感到惊讶。

WWGD?什么是安全地使用不受信任的参数的pythonic方式,当你想要做的就是比较它的幅度?

1 个答案:

答案 0 :(得分:0)

如果你真的想验证参数是否是合适的数字类型,那么测试它是否是相应的numeric abstract base class的实例,可能是:

    import numbers
    ...
    if not isinstance(limit, numbers.Real):
        ... # react to the bad argument type

据推测,在这种情况下,你会抛出TypeError例外。

在班级的__init__方法中执行此操作,以便检测问题并尽可能接近调用者的原始错误进行报告。这比等待一段不确定的时间要好得多,并且当程序开始使用计数器时最终会爆炸,此时异常回溯对于确定问题的起因将远没有帮助。

如果您感觉偏执,您还可以检查构造函数中此参数的值是否大于零,如果不是则抛出ValueError异常。