Вопрос о семантике, действительно.isinstance (foo, bar) vs type (foo) is bar
До недавнего времени, если бы мне пришлось выполнять какую-либо проверку типов на структуре, я бы использовал type(obj) is list
et. и др. Однако после вступления в СО я заметил всех (и я имею в виду EVERYONE) вместо этого использует isinstance(obj,list)
. Кажется, они синонимы, и timeit
показывает почти ИДЕНТИЧНУЮ скорость между ними.
def a(): return type(list()) is list
def b(): return isinstance(list(),list)
from timeit import timeit
timeit(a)
# 0.5239454597495582
timeit(b)
# 0.5021292075273176
Действительно, даже dis
соглашается они синонимичны, за исключением type is
«s COMPARE_OP
from dis import dis
dis(a)
# 2 0 LOAD_GLOBAL 0 (type)
# 3 LOAD_GLOBAL 1 (list)
# 6 CALL_FUNCTION 0 (0 positional, 0 keyword pair)
# 9 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
# 12 LOAD_GLOBAL 1 (list)
# 15 COMPARE_OP 8 (is)
# 18 RETURN_VALUE
dis(b)
# 2 0 LOAD_GLOBAL 0 (isinstance)
# 3 LOAD_GLOBAL 1 (list)
# 6 CALL_FUNCTION 0 (0 positional, 0 keyword pair)
# 9 LOAD_GLOBAL 1 (list)
# 12 CALL_FUNCTION 2 (2 positional, 0 keyword pair)
# 15 RETURN_VALUE
Я искренне считаю его более читаемым сказать if type(foo) is list:
чем if isinstance(foo,list):
, первый в основном только псевдо- код, а второй вызывает некоторую функцию (которую я должен искать каждый раз, чтобы быть isinstance
или instanceof
) с некоторыми аргументами. Это не похоже на листинг типов, и нет явного способа узнать, проверяет ли isinstance(a,b)
, является ли b
экземпляром a
или наоборот.
Я понимаю от this question, что мы используем isinstance
, потому что это приятнее о наследовании. type(ClassDerivedFromList) is list
не удастся, а isinstance(ClassDerivedFromList,list)
преуспеет. Но если я проверю, что ВСЕГДА БЫТЬ БАЗОВЫМ ОБЪЕКТОМ, что я действительно теряю от выполнения type is
?
Я специально задумываюсь о реорганизации функции, которую я написал около 6 месяцев назад, которая принимает либо строку, либо список строк. Единственный вход для этой функции будет EVER быть 'str' или' list', поэтому делает 'if type (foo) is str: _handle_str (foo) else: _handle_list (foo)' действительно плохая практика? –
@adsmith: вы используете Python 3? Если нет, ваш код просто сломался, если вы закончите строку с юникодом. – DSM
@ DSM Я так понимаю, но я ценю подводные камни 'unicode' vs' str'. –