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

Types 比较不受信任的简单参数的Pythonic方法,types,compare,python,trusted-vs-untrusted,Types,Compare,Python,Trusted Vs Untrusted,我的基本理念是:不要请求许可,只管去做,请求原谅。例如,不需要是一个文件就可以有一个.read()方法,当您想读取一个类似文件的对象时,当您发现事情“正常”时,您会感谢自己。然而,对于像文件这样的复杂对象,这比像数字这样的简单对象更容易理解 所以我试着写一个非常简单的类。细节无关紧要,但它有一个内部计数器,当计数器超过限制时,它必须执行某些操作。该限制在创建对象时作为参数提供 现在我在考虑防御性编程。显然,我希望我的极限是一个整数,或者至少是一个比较像整数的东西。它可能比这弱,因为如果它是浮点,

我的基本理念是:不要请求许可,只管去做,请求原谅。例如,不需要是一个文件就可以有一个.read()方法,当您想读取一个类似文件的对象时,当您发现事情“正常”时,您会感谢自己。然而,对于像文件这样的复杂对象,这比像数字这样的简单对象更容易理解

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

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

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

if isinstance(limit,(int,long,float)):
但是这里有很多“不测试,尝试除外”的答案,所以我知道这是不和谐的。最好使用限制,并等待抛出异常。所以我试了一下:除了各种类型的限制

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

因此,我使用了RTFM,结果发现compare并没有为混合类型引发异常,这与“容器中的x”的操作有关,对于该操作,等式是在任意类型上测试的。对于不同的类型,它总是返回不相等的结果,但大小比较虽然一致,但却是任意的。如果混合类型的量值比较总是返回False,我可能会使用它,但它也会愉快地返回True

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

limit+0
所以我可以说

if counter >= (limit+0)
如果limit不是一个数字,则抛出所需的异常。但这几乎让人感到困惑。我正在对表达式做一些额外的操作,在后门做一个类型测试。任何代码优化程序或其他编辑器都会删除明显冗余的算术运算。这就像看一个物体的重量是否和鸭子一样,看它是否是木头做的,因此可以作为女巫(某种程度上)烧掉

更明确的可能性是

if counter >= int(limit)
这至少有一些内在的解释。这并不完全符合我在任何情况下都希望发生的事情,但现在已经足够了,不会让任何人感到惊讶


那么WWGD呢?当您只想比较参数的大小时,安全使用不可信参数的pythonic方法是什么?

如果您确实想验证参数是否为合适的数值类型,那么请测试它是否是合适参数的实例,也许:

    import numbers
    ...
    if not isinstance(limit, numbers.Real):
        ... # react to the bad argument type
大概在这种情况下,您将抛出一个
TypeError
异常

在类的
\uuuu init\uuuu
方法中执行此操作,以便检测并报告问题,尽可能接近调用方的原始错误。这比等待一段不确定的时间并最终在程序开始玩计数器时崩溃要好得多,在这一点上,异常回溯对确定问题的根源没有多大帮助


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

恭喜,你现在可以通过谷歌搜索“YAGNI”并理解它。谢谢,我有,c2.com上有很多阅读。不幸的是,将字符串传递给需要比较的对象(如int)的愚蠢用户是我,所以我觉得我需要它。但是,我正在做的一部分工作是学习Python,以及编写我需要的东西,我正在尝试完成事情的方法。但我还是想知道python的方式是什么,这里你不需要太多的泛化,而不是防御性编程。你会需要一个非整数的计数器限制吗?您是否觉得这是一个需要抽象层的重要概念?