关于typechecking:Python类型检查

Type checking of arguments Python

本问题已经有最佳答案,请猛点这里访问。

有时需要检查python中的参数。例如,我有一个函数,它接受网络中其他节点的地址作为原始字符串地址,或者接受封装其他节点信息的类节点。

我使用类型(0功能,如:

1
2
3
4
if type(n) == type(Node):
    do this
elif type(n) == type(str)
    do this

这是一个很好的方法吗?

更新1:python 3有函数参数的注释。可以使用以下工具进行类型检查:http://mypy-lang.org/


使用isinstance()。。。。。。。抽样: </P >

1
2
3
4
5
if isinstance(n, unicode):
    # do this
elif isinstance(n, Node):
    # do that
...


1
2
3
4
>>> isinstance('a', str)
True
>>> isinstance(n, Node)
True


你也可以使用吧抓到型,如果必要的检查: </P >

1
2
3
4
5
6
7
8
9
10
def my_function(this_node):
    try:
        # call a method/attribute for the Node object
        if this_node.address:
             # more code here
             pass
    except AttributeError, e:
        # either this is not a Node or maybe it's a string,
        # so behavior accordingly
        pass

你可以看到一个实例在本月初在Python中的第二对发电机组(197页在我的版)我相信在cookbook Python。多时报捕集的AttributeErrorTypeError是simpler和apparently更快。它也可以工作,最好在这个大陆的,那么你是不知道你到一个特别的继承树(例如,你的对象可以是一个Node或它可能采取的其他面向,已同样的行为作为一种Node)。 </P >


你的声音像是在一个"通用函数"这一behaves型有不同的arguments派出所。这是一位怎样样,你会得到一个不同的函数,当你呼叫的一种方法是从一个不同的对象,但是,比只使用第一argument(面向/自)查找到你的函数,而不是使用的全部arguments。。。。。。。 </P >

turbogears使用的东西,这样的方法断如何转化到JSON对象-如果我correctly召回。 </P >

我的一条从IBM使用dispatcher package for this sort of的事: </P >

从那条: </P >

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import dispatch
@dispatch.generic()
def doIt(foo, other):
   "Base generic function of 'doIt()'"
@doIt.when("isinstance(foo,int) and isinstance(other,str)")
def doIt(foo, other):
    print"foo is an unrestricted int |", foo, other
@doIt.when("isinstance(foo,str) and isinstance(other,int)")
def doIt(foo, other):
    print"foo is str, other an int |", foo, other
@doIt.when("isinstance(foo,int) and 3<=foo<=17 and isinstance(other,str)")
def doIt(foo, other):
    print"foo is between 3 and 17 |", foo, other
@doIt.when("isinstance(foo,int) and 0<=foo<=1000 and isinstance(other,str)")
def doIt(foo, other):
    print"foo is between 0 and 1000 |", foo, other


好的,具体的类型检查arguments在Python中是不必要的。它是永远 必要的。 </P >

如果你的代码accepts地址为rawstring或作为一个Node面向,你的 设计是破碎的。 </P >

这是从的事实是,如果你不知道已经在一型的 面向在你自己的程序的,当时你正在做的事情就已经错了。 </P >

具体的类型检查hurts代码重用和性能的影响。一种函数 这performs不同的事情depending型的"面向通过 易卒中型是错误的和有一个行为的努力来理解和maintain。。。。。。。 </P >

你有saner下面的选项: </P >

  • 做一个Node面向constructor那accepts rawstrings,或一个函数 这converts串在Node对象。让你的函数的假设 通过argument是一个Node面向。这是通的,如果你需要一个通 字符串的函数,你就做: </P >

    1
    myfunction(Node(some_string))

    那是你的最佳选择,它是干净的,容易的理解和maintain。。。。。。。 任何人阅读的代码immediatelly understands什么是发生, 和你不要typecheck。。。。。。。 </P >

  • 这两个函数,一个是accepts Node对象和一个accepts… rawstrings。。。。。。。你能让一个呼叫其他internally,在最 convenient通(myfunction_str可以创建一个面向Node和呼叫 myfunction_node,或其他办法左右)。 </P >

  • 麦克Node对象有一个__str__方法和在你的函数, 呼叫str()对收到的argument。。。。。。。那通你总是得到一个字符串 通过coercion。。。。。。。 </P >

  • 在任何情况下,不typecheck。。。。。。。这是完全不必要的和有只读 downsides。。。。。。。重构你的代码,而不是在一路,你不需要typecheck。。。。。。。 你只有在做得到的利益),都在短期和长期运行。 </P >