前言
先前使用 Python 測試物件、變數是否為指定的『類別』或『資料型態』 時(e.g. int
、float
、bool
、str
、list
……),都是使用 type()
方法,但其實 Python 有提供 isinstance()
函式,此法是較好的作法,不僅執行速度較快,也適用於自己建立的 Class 物件繼承(type()
不考慮物件繼承,若為繼承類別的物件不會判斷與父類是相同類別)數,來看看他有哪些特性與用法吧!
如何在 Python 中使用 isinstance() 函數
語法
isinstance()
函數需傳入兩個必要參數,若檢查的結果相符,回傳結果為 True
,反之為 False
object
: 此參數傳入指定的 類別(Class) or 變數
classinfo
: 此參數傳入指定類別(Class)名稱或變數型別,另外支援以tuple
形式傳遞多個類別 or 資料型別的值
語法規則:
1
| isinstance(object, classinfo)
|
範例1 - 檢查變數的型別
檢查 numb 這項變數的型別是否為 str
(字串)
1 2 3 4 5 6 7
| word= "hello" result = isinstance(word, str) print(result) if result: print("Y") else: print("N")
|
output:
由輸出結果可知,透過 isinstance()
函式對 word 變數做型別檢查是否為 string
,回傳結果為 True
表類型相符。
isinstance()
函式亦能對其他 Pyhton 內建的型別(e.g. )進行檢查,以下列出幾個範例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| numb = 10 print(isinstance(number, int))
print(isinstance(number, float))
PI = 3.14
print(isinstance(PI, float))
complex_num = 1 + 2j print(isinstance(complex_num, complex))
names_list = ["Tom", "Jack", "Jason"] print(isinstance(names_list, list))
people = {"Tom": 80, "Jack": 70, "Jason": 90} print(isinstance(people, dict))
names_tuple = ("Emma", "Jackson", 'Amy') print(isinstance(names_tuple, tuple))
numbs = {1, 2, 3, 4} print(isinstance(numbs, set))
|
注意:
若將 isinstance()
與任何帶有 None
的變數或物件一起使用時,回傳結果為 False
1 2 3 4 5
| none_var = None
empty_str = '' print(isinstance(none_var, float)) print(isinstance(empty_str, str))
|
範例2 - 檢查類別(Class)
除了針對變數做型別檢查外,亦可對類別檢查
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class Animal: def __init__(self, name, age): self.name = name self.age = age
class Student: def __init__(self, name, degree): self.name = name self.degree = degree
ani = Animal("Amy", 3) stud = Student("Tom", "master")
print(isinstance(ani, Animal))
print(isinstance(stud, Student))
|
範例3 - 檢查變數的多個型別
前述第一個範例只有針對單一型別做檢查,isinstance()
提供一次檢查多個型別的功能,參數可以tuple
形式一次帶入多個資料型別。例如我們想確認該變數是否為數值時,可能同時包含 int
, float
兩種型別,以下作為範例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| def is_number(numb): if isinstance(numb, (int, float)): print(f'變數 {numb} 為數值型別的實例') else: print(f'變數 {numb} 非數值型別的實例')
n1 = 80 is_number(n1)
n2 = 55.70 is_number(n2)
n3 = '20' is_number(n3)
|
範例4 - 檢查類別繼承(Class Inheritance)
isinstance
函式也可針對物件導向的類別(Class)繼承(如子類別的物件也是父類別的一種類型)做檢查,若 instance()
的 classinfo
參數是目標類別的父類別,則回傳 True
,反之為 False
,來看個例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Vehicle(object): def __init__(self, category): self.category = category
def display(self): print("Vehicle: ", self.category)
class Car(Vehicle): def __init__(self, category, color): self.category = category self.color = color
def display(self): print("Category: ", self.category, "color: ", self.color)
obj = Car("car", "red")
print(isinstance(obj, Car)) print(isinstance(obj, Vehicle))
|
比較 type() 與 isinstance() 兩者的速度
type()
1
| python3 -m timeit -s "variable = 'test'" "type(variable) is str"
|
output: 5000000 loops, best of 5: 43.7 nsec per loop
isinstance()
1
| python3 -m timeit -s "variable = 'test'" "isinstance(variable, str)"
|
output: 10000000 loops, best of 5: 35.5 nsec per loop
分別執行上述兩者針對同一變數是否為字串時的比對時,執行速度是 isinstance()
較佳。
總結
isinstance
通常是比較類型的首選。藉由上面幾個範例可知,它不僅更快,同時考慮繼承,下次若要對資料做型別檢查時,就優先考慮 isinstance
這個函式吧~
Reference