StringType и NoneType в python3.x
У меня есть кодовая база, которая использует StringType и NoneType (тип модуля) в кодовой базе python2.x. При портировании на Python3 тесты завершились неудачно, поскольку в модулях типов в Python3.x нет вышеупомянутых двух типов.
Я решил проблему, заменив их "str" и "None" соответственно. Мне было интересно, есть ли другой (правильный) способ сделать это. То, что я сейчас делаю, определенно работает, но я сомневаюсь.
Должен ли я придерживаться подхода, который я выполнил, или что-то не так в том, что я сделал? Если да, то как его исправить?
Ответы
Ответ 1
Проверка None обычно выполняется вызовом obj is None
, в то время как проверка строки обычно равна isinstance(obj, str)
. В Python 2.x для определения как строки, так и юникода вы можете использовать isinstance(obj, basestring)
.
Если вы используете 2to3
, этого достаточно, но если вам нужно иметь одну часть кода, работающую как в Py2, так и в Py3, вы можете получить что-то вроде этого:
try:
return isinstance(obj, basestring)
except NameError:
return isinstance(obj, str)
Ответ 2
По возможности я бы рекомендовал вам избегать значений в types
, если их значения очевидны; поэтому для чего-то вроде привязки метода к объекту используйте types.MethodType
, но для types.StringTypes
используйте (str, unicode)
или, скорее, basestring
.
В этой ситуации я бы сделал следующее:
- Используйте
obj is None
или obj is not None
, а не isinstance(obj, NoneType)
или not isinstance(obj, NoneType)
.
- Используйте
isinstance(obj, basestring)
вместо isinstance(obj, StringTypes)
- Используйте
isinstance(obj, str)
вместо isinstance(obj, StringType)
Затем, когда вам нужно распространять для Python 3, используйте 2to3
. Тогда ваш basestring
станет str
, а остальные будут продолжать работать так, как раньше.
(Также учтите это, в частности, разницу между StringType
и StringTypes
:
types.UnicodeType == unicode
types.StringType == str
types.StringTypes == (str, unicode)
)