如何正确确定类型?

时间:2014-09-21 04:33:40

标签: python

这可能已被问过一百次,但你是自己成功的产物!

在Python中,我在其他人的代码中看到了这一点

if type(number) != type(1):

有没有充分的理由这样做,不应该

if type(number) != int

这是更好的方法吗?

这是历史性的吗?

3 个答案:

答案 0 :(得分:3)

这两种方法都不正确。

正确的方法是使用isinstance()

if not isinstance(number, int):

这确保不允许子类

极为罕见的案例中,您必须绝对只禁止int并允许子类,type()使用not is;类型是单身人士:

if type(number) is not int:

更多的pythonic是使用请求宽恕而不是许可;将值视为整数,直到证明为止(例如,例外)。

答案 1 :(得分:3)

没有充分的理由去做这些。这可能是某人习惯于编写Python代码的其他强类型语言的症状。

如果您必须(但请再次考虑这一点),您应该使用isinstance()

>>> isinstance('1', str)
True

Python是一种用于同意成年人的语言,这是一种说法我们希望你知道自己在做什么的奇特方式;就像那个着名的"强大的力量带来了巨大的责任"引用你最喜欢的超级英雄电影。

在Python中,对象应该表现得很好,并且你不应该有这样的惊喜来进行显式类型检查。

通常进行此类型检查以确保您可以对值执行某些操作。一个简单的例子是添加两个东西(使用+符号),您可能想要检查它们是否是某种数字。显然'hello' + 5无效。

所以你可能想写这样的代码:

def add_things(first, second):
   if type(first) == int and type(second) == int:
       print(first+second)

然后在阅读完这些答案后,您将上述内容更改为:

def add_things_smarter(first, second):
   if isinstance(first, int) and isinstance(second, int):
       print(first+second)

但是,最好尝试进行操作,然后处理错误:

def add_things_better(first, second):
    try:
       print(first+second)
    except ValueError:
       print("I can't add {} + {}".format(first, second))

这被称为:

  

EAFP

     

比获得许可更容易请求宽恕。这个常见的Python   编码风格假定存在有效的键或属性   如果假设被证明是假的,则捕获异常。这干净又快   风格的特点是存在许多尝试和除外   声明。该技术与许多人共同的LBYL风格形成鲜明对比   其他语言,如C.

这是来自glossary section of the documentation,在那里你会找到LBYL的定义(Look Before You Leap)。

答案 2 :(得分:0)

Martijn Pieters和Burhan Khalid给出了很好的答案,但整个故事都没有。

在Python中,通常使用值的最佳方法是假设它是正确的类型。您应该避免使用基于类型的调度type(x) is type(y)检查是什么),除非它非常重要。

所以不要这样做:

if type(number) is int:
    do_int_stuff
else:
    not_an_int

你应该这样做:

try:
    do_int_stuff
except NotTheRightTypeForThatException:
    not_an_int

更好的是,首先不要进入那个位置;只是拥有合适的类型。尽管像Java这样的语言允许你按类型重载函数,但在Python中,通常最好假设一个函数采用强制的非可选接口(比如需要添加或可迭代)而且从不给他们一些他们不支持的东西。


次适合进行基于类型的调度,而这两种类型(isinstancetype(x) is type(y))都有它们的位置,尽管前者更为常见。

一次使用isinstance是为新类型实施运算符(如+-*/)。你想要

X() * X()

工作,但你不想说什么

X() * Y()

表示除非您知道自己正在做正确的事情。造成这种情况的原因并不重要,但涉及这两种类型需要合作来决定运行的原因。您通常会进行isinstance检查,因为如果您实施

int(4) * int(2)

和某个子类int

class MyInt(int): ...

你不希望*破产!


type(X) is type(Y)的用法非常罕见。一个实际案例是您连接两个类型系统;当将一种类型转换为另一种语言的模拟(或者用类似JSON的方式将其序列化)时,要求确切类型更有意义。特别是,这使得往返(转换和转换)保持无损。

通常情况下,你知道什么时候需要这个,而且它也比其他人少得多。