Python是一種動态語言,比如建立一個變量,一開始引用的是字元串,随後就可以再引用整數或者浮點數,解釋器對這種變換也接受。這與類似Java那樣的語言就完全不同了。
name = "Sebastian"
# 下面示範的就是動态語言特點
name = 42
name = None
name = Exception() # 引用一個執行個體對象
複制
在程式中,檢查變量所引用的對象是什麼類型,對于Python程式也是必要的。一般我們會實用
type()
或者
isinstance()
這兩個内置函數。
>>> variable = "hello"
>>> type(variable) is str
True
>>> isinstance(variable, str)
True
複制
下面比較一下這兩個函數的性能:
$ python -m timeit -s "variable = 'hello'" "type(variable) is int"
2000000 loops, best of 5: 102 nsec per loop
$ python -m timeit -s "variable = 'hello'" "isinstance(variable, str)"
5000000 loops, best of 5: 72.8 nsec per loop
複制
type
比
instance
慢了 40% (102/72.8 = 1.40).
有人也實用
type(variable) == str
種方式判斷某個對象的類型,雖然此方法是可行的,但不提倡,因為:
• == should be used when you want to check the value of a variable. We would use it to see if the value ofvariable is equal to "hello". But when we want to check if variable is a string, is operator is more appropriate. For a more detailed explanation of when to use one or the other, check this article. • == is slower:
-
應該用于檢查對象是否與另外一個對象相等。我們可以用它來檢視變量的值是否等于==
,但是想要檢查變量是否是一個字元串時,不要用這個符号,而是改用hello
操作符更合适。is
-
的執行速度更慢,可以用下面的代碼檢驗:==
$ python -m timeit -s "variable = 'hello'" "type(variable) == str"
2000000 loops, best of 5: 114 nsec per loop
複制
isinstance
和
type
之間除了前面示範的執行速度不同之外,還有别的差別嗎?
有!而且下面要說的差別,比執行速度還重要。
-
的傳回值是一個對象的類型(類),可以用它來檢查type
的類型是否為variable
。str
-
要檢查第一個參數對象是不是第二個參數所指定的類的執行個體,例如isinstance
是variable
類的一個執行個體嗎?或者,檢查是不是第二個參數所指定的類的子類的示例,例如str
是variable
子類的一個執行個體嗎?str
這在實踐很有用。假設自定義一個類,它類似于清單,但方法可以更多一些。是以我們可以把
list
作為這個類的父類,然後在這個類裡面寫其他的方法,基本樣式如下:
class MyAwesomeList(list):
# Add additional functions here
複制
但是現在,如果我們将這個新類與一個清單進行比較,
type
和
isinstance
會傳回不同的結果!
>>> my_list = MyAwesomeList()
>>> type(my_list) is list
False
>>> isinstance(my_list, list)
True
複制
輸出結果不同。
isinstance
檢查
my_list
是否是
list
的一個執行個體(它不是)、或者是否是
list
的一個子類的執行個體(它是,因為
MyAwesomeList
是
list
的一個子類)。這個細節,有時候會導緻BUG。
isinstance
通常是判斷對象類型的首選方法。它不僅更快,而且還考慮了繼承,這通常是我們所需要的。不過,在Python中,我們通常不需要檢查某個對象的類型,隻需要關注它能不能具備像字元串或清單那樣的方法和屬性,這就是著名的“鴨子檢驗”。是以,隻需要使用
isinstance
即可。
另一方面,如果想顯式地檢查給定對象是否屬于某一特定類型(而不是它的子類),可以使用
type
,但通常用這樣的語句
type(var) is some_type
,而不是
type(var) == some_type
。
記住,編寫函數的時候,不檢查對象類型,是Python的慣例,不要把Java的習慣帶過來。