Python在定義變數的時候不用指明具體的的型別,直譯器會在執行的時候會自動檢查變數的型別,並根據需要進行隱式的型別轉化,因為Python是動態語言,所以一般情況下是不推薦進行型別轉化的。
比如進行”+”操作時,如果加號兩邊是資料就進行加法操作,如果兩邊是字串就進行字串連線操作,如果兩邊是列表就進行合併操作,甚至可以進行復數的運算。
直譯器會在執行時根據兩邊的變數的型別呼叫不同的內部方法。當加號兩邊的變數型別不一樣的時候,又不能進行型別轉化,就會丟擲TypeError的異常。
types模組從Python2到Python3的變化
在實際的開發中,為了提高程式碼的健壯性,我們還是需要進行型別檢查的。而進行型別檢查首先想到的就是用types(),比如使用types判斷一個int型別:
Source Code:
#!/usr/bin/env python2.6
#Author: nock.chen
from types import *
mylist = [`nock`, 100, `100`, `IT`]
def delete(mylist, item):
if type(item) is IntType:
mylist.remove(item)
delete(mylist, 100)
print(mylist)
複製程式碼
Result:
[`nock`, `100`, `IT`]
複製程式碼
我們在types模組中可以找到一些常用的型別,在2.6.9中顯示的結果:
types.BooleanType # bool型別
types.BufferType # buffer型別
types.BuiltinFunctionType # 內建函式,比如len()
types.BuiltinMethodType # 內建方法,指的是類中的方法
types.ClassType # 類型別
types.CodeType # 程式碼塊型別
types.ComplexType # 複數型別
types.DictProxyType # 字典代理型別
types.DictType # 字典型別
types.DictionaryType # 字典備用的型別
types.EllipsisType # Ellipsis型別
types.FileType # 檔案型別
types.FloatType # 浮點型別
types.FrameType # 框架物件的型別
types.FunctionType # 函式型別
types.GeneratorType # 通過呼叫生成器函式生成的generator-iterator物件型別
types.GetSetDescriptorType # 用PyGetSetDef(如FrameType)在擴充套件模組中定義的物件的型別
types.InstanceType # 例項型別
types.IntType # int型別
types.LambdaType # lambda型別
types.ListType # 列表型別
types.LongType # long型別
types.MemberDescriptorType # 在擴充套件模組中定義的物件型別,包括PyMemberDef,如datetime.timedelta.days
types.MethodType # 方法型別
types.ModuleType # module型別
types.NoneType # None型別
types.NotImplementedType # NotImplemented的型別
types.ObjectType # object型別
types.SliceType # slice()返回的物件型別
types.StringType # 字串型別
types.StringTypes # 一個包含StringType和UnicodeType的序列,用於方便對任何字串物件進行檢查。
types.TracebackType # 在sys.exc_traceback中發現的traceback物件的型別。
types.TupleType # 元組型別
types.TypeType # 型別本身
types.UnboundMethodType # 另一個名字for MethodType
types.UnicodeType # Unicode字元字串的型別(例如,u ` spam)
types.XRangeType # xrange()返回的範圍物件的型別
複製程式碼
官網介紹:https://docs.python.org/2/library/types.html
到了Python3版本,types
模組方法已經明顯減少了很多,具體如下:
types.BuiltinFunctionType
types.BuiltinMethodType # 內建函式的型別,如len()或sys.exit(),以及內建類的方法。(這裡,“內建”的意思是“用C寫”。)
types.CodeType # 通過compile()返回的程式碼物件型別。
types.DynamicClassAttribute
types.FrameType # 框架物件的型別,如在tb中發現的。tb_frame如果tb是一個traceback物件。
types.FunctionType
types.GeneratorType # 由生成器函式建立的generator - iterator物件型別。
types.GetSetDescriptorType # 用PyGetSetDef(如FrameType)在擴充套件模組中定義的物件的型別。
types.LambdaType # 由lambda表示式建立的使用者定義函式和函式的型別。
types.MappingProxyType
types.MemberDescriptorType
types.MethodType # 使用者定義類例項的方法型別。
types.ModuleType
types.SimpleNamespace
types.TracebackType # traceback物件的型別,如sys.exc_info()
types.new_class
types.prepare_class
複製程式碼
官網介紹:https://docs.python.org/3/library/types.html#module-types
不推薦使用type檢查型別
從上面的Python2到Python3的版本升級過程中,types模組方法有所減少。如果使用type方法也會存在如下問題:
如上所示說明i和n的型別是不一樣的,而實際上UserInt是繼承int的,所以這個判斷是存在問題的,當我們對Python內建型別進行擴充套件的時候,type返回的結果就不夠準確了。我們再看一個例子:
type比較的結果a和b的型別是一樣的,結果明顯是不準確的。這種古典類的例項,type返回的結果都是一樣的,而這樣的結果不是我們想要的。對於內建的基本型別來說,使用tpye來檢查是沒有問題的, 可是當應用到其他場合的時候,type就顯得不可靠了。
這個時候我們就需要使用內建函式isinstance
來進行型別檢查,示例如下:
isinstance(object, class_or_type_or_tuple)
複製程式碼
object表示物件,classinfo可以是直接或間接類名、基本型別或者有它們組成的元組。
nock:ucode nock$ python3
Python 3.5.1 (default, Dec 26 2015, 18:08:53)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> isinstance(2, float)
False
>>> isinstance(2, int)
True
>>> isinstance((2, 3), list)
False
>>> isinstance((2, 3), tuple)
True
>>> isinstance({`name`: `nock`}, tuple)
False
>>> isinstance({`name`: `nock`}, dict)
True
>>> isinstance([1, 100, 101], (str, list, tuple))
True
>>> isinstance(2 ** 31, dict)
False
>>> isinstance(2 ** 31, long)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name `long` is not defined
>>> isinstance(2 ** 31, int)
True
複製程式碼
Python2有為非浮點數準備的int
和long
型別。int型別的最大值不能超過sys.maxint
,而且這個最大值是平臺相關的。可以通過在數字的末尾附上一個L
來定義長整型,顯然,它比int型別表示的數字範圍更大。在Python3裡,只有一種
整數型別int
,大多數情況下,它很像Python2裡的長整型。由於已經不存在兩種型別的整數,所以就沒有必要使用特殊的語法去區別他們, 進一步閱讀:PEP 237。
最後在Python中型別的判斷你最好的方法是利用內建函式isinstance
完成是最佳體驗。
官網介紹:https://docs.python.org/3/library/functions.html#isinstance