2012-06-25 20 views
0

我得到的基本理念是不要求权限,只要做到这一点,并要求原谅。例如,它不需要是一个具有.read()方法的文件,稍后当您想要读取类似文件的对象时发现“正常工作”时,您会感谢您自己。然而,对于像文件这样的复杂对象而言,要比简单的对象(比如数字)容易得多。Pythonic的方式来比较不可信的简单参数

所以我想写一个非常简单的类。细节并不重要,但它有一个内部计数器,并且在计数器超出限制时必须执行某些操作。创建对象时,该限制作为参数提供。

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

虽然类的用户会知道这个参数应该是一个整数,但我希望对象做一些不令人惊讶的事情,如果它不是。我首先想到的是检查,我实际上是由

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

有一些,但有任意数量的“不测试,尝试不同的”关于答案在这里,所以我知道这是unpythonic。最好使用限制,并等待抛出异常。所以,我想这是一个尝试中:除了各类极限

if counter >= limit: 

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

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

如果我尝试使用非NUMERICS其他整数类似的行为,我得到预期的异常,比如这个字符串+号抛出一个TypeError

limit+0 

所以我可以说

if counter >= (limit+0) 

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

更明确的可能性是

if counter >= int(limit) 

其中至少有一些内置的解释,不正是这样做,我想在任何情况下发生了什么,但它足够的时刻,它不会让任何人感到惊讶。

那么WWGD?当你想要做的只是比较它的大小时,安全地使用不可信参数的pythonic方式是什么?

+0

恭喜,您现在可以使用Google搜索“YAGNI”并了解它。 – Kos

+0

谢谢,我有,在c2.com有很多阅读。不幸的是,将字符串传递给像int这样需要比较的笨笨用户是我的,所以我觉得我需要它。但是,我正在学习的一部分是学习Python,以及编写我需要的东西,而我正在玩弄完成任务的方式。但我仍然想知道Pythonic的方式。 –

+0

你在这里不需要的是太多的通用性,而不是防御性的编程。你是否需要一个不是int的反限制?你觉得这是一个需要抽象层的重要概念吗? – Kos

回答

0

如果你确实想验证的说法是一个合适的数字类型,然后测试它是否是合适的numeric abstract base class的一个实例,也许是:

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

想必在这种情况下,你会扔一个TypeError异常。

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

如果你觉得偏执,你也可以在构造函数中检查这个参数的值是否大于零,如果不是,则抛出一个异常ValueError