2012-09-10 37 views
5

是否有一種很好的方法來檢查對象o是否爲內建Python函數?Python - 測試對象是否爲內置函數

我知道可以使用例如

type(o) == type(pow) 

因爲類型(POW)是 'builtin_function_or_method'。

但是有沒有更好的方法?

回答

9

類型模塊:

>>> import types 
>>> types.BuiltinFunctionType 
<type 'builtin_function_or_method'> 

不過,如果你看看引擎蓋下,你會發現它不是從你現在在做什麼不同。

所以,你的情況,使用

isinstance(o, types.BuiltinFunctionType) 
+0

正如@ iMom0他回答說 - 你可以用'isinstance(X,Y)',而不是使用'型(X)==型(Z)',我認爲這是更Python :) – slallum

+0

你'對,我在想什麼。 –

+1

這不會告訴你函數是否內置,它會告訴你它是否是本機編譯的C函數。帶有C擴展的第三方模塊也會將這些功能報告爲這種類型。 –

3

試試這個:

>>> import types 
>>> isinstance(pow, types.BuiltinFunctionType) 
True 
>>> def a(): 
    pass 
>>> isinstance(a, types.BuiltinFunctionType) 
False 
2

,你也可以做

import __builtin__ 
o in __builtin__.__dict__.values() 

,或者在CPython的:

o in __builtins__.__dict__.values() 

但請注意,您在此處依賴實施細節。


>>> pow in __builtins__.__dict__.values() 
True 
>>> def a(): 
... pass 
... 
>>> a in __builtins__.__dict__.values() 
False 
>>> 
0

這取決於你的「內置」的意思。

使用__builtins__

如果要檢查你的函數是在Python解釋器內置的功能之一,你可以使用

>>> pow in __builtins__.__dict__.values() 
True 
>>> __builtins__.__dict__['pow'] 
<built-in function pow> 

Python解釋器有許多內置 - 常量,函數,類型和例外,它們包含在字典__builtins__.__dict__中。

使用BuiltinFunctionType

如果在另一方面,你要檢查你函數類型的BuiltinFunctionType可以使用types模塊

>>> import types 
>>> isinstance(pow, types.BuiltinFunctionType) 
True 

使用inspect

或者inspect.isbuiltin(只是一個包裝isinstance(object, types.BuiltinFunctionType)

>>> import inspect 
>>> inspect.isbuiltin(pow) 
True 

注意在BuiltinFunctionType術語「內置」的意思是「用C寫的。」

請看下面的例子:

>>> from math import factorial 
>>> isinstance(factorial, types.BuiltinFunctionType) 
True 

factorial功能BuiltinFunctionType類型,但它不是在解釋

>>> factorial in __builtins__.__dict__.values() 
False 

這是因爲math模塊在Python由一個內置函數包裝C數學庫函數。

能夠檢測BuiltinFunctionType是有用的,因爲對於用Python編寫的函數,可以檢查源代碼而無需打開源文件。

>>> import random 
>>> isinstance(random.random, types.BuiltinFunctionType) 
True 
>>> inspect.getsource(random.random) 
# returns TypeError 
>>> isinstance(random.uniform, types.BuiltinFunctionType) 
False 
>>> from __future__ import print_function # if using Python 2.* 
>>> print(inspect.getsource(random.uniform)) 
    def uniform(self, a, b): 
     "Get a random number in the range [a, b) or [a, b] depending on rounding." 
     return a + (b-a) * self.random()