Как преобразовать Nonetype в int или string?
У меня есть значение Nonetype
x
, это обычно число, но может быть None
. Я хочу разделить его на число, но Python повышает:
TypeError: int() argument must be a string or a number, not 'NoneType'
Как я могу это решить?
Ответы
Ответ 1
В одном из комментариев вы говорите:
Как-то я получил значение Nonetype, оно должно быть int, но теперь это объект Nonetype
Если это ваш код, выясните, как вы получаете None
, когда вы ожидаете номер, и остановите , что.
Если это кто-то еще, узнайте условия, при которых он дает None
, и определите разумное значение для этого, с обычным условным кодом:
result = could_return_none(x)
if result is None:
result = DEFAULT_VALUE
... или даже...
if x == THING_THAT_RESULTS_IN_NONE:
result = DEFAULT_VALUE
else:
result = could_return_none(x) # But it won't return None, because we've restricted the domain.
Нет причин для автоматического использования 0
здесь - решения, зависящие от "ложности" None
, предполагают, что вы захотите этого. DEFAULT_VALUE
(если он существует) полностью зависит от цели вашего кода.
Ответ 2
int(value or 0)
Это будет использовать 0 в случае, когда вы предоставляете любое значение, которое Python считает False
, например None, 0, [], "" и т.д. Так как 0 False
, вы должны использовать только 0 в качестве альтернативное значение (иначе вы найдете, что ваши 0s превращаются в это значение).
int(0 if value is None else value)
Это заменяет только None
на 0. Поскольку мы специально тестируем None
, вы можете использовать другое значение в качестве замены.
Ответ 3
Обычный "Pythonic" способ справиться с подобной ситуацией известен как EAFP: "Проще просить прощения, чем разрешения". Что обычно означает написание кода, который предполагает, что все в порядке, но затем оборачивает его блоком try..except
всякий случай для обработки вещей, когда это не так.
Вот этот стиль кодирования применяется к вашей проблеме:
try:
my_value = int(my_value)
except TypeError:
my_value = 0 # or whatever you want to do
answer = my_value / divisor
Или, может быть, еще проще и чуть быстрее:
try:
answer = int(my_value) / divisor
except TypeError:
answer = 0
Обратный и более традиционный подход известен как LBYL, что означает "Посмотри, прежде чем прыгнуть", - это то, что предложили @Soviut и некоторые другие. Дополнительное освещение этой темы см. В моем ответе и связанных комментариях к вопросу. Определите, присутствует ли ключ в словаре в другом месте на этом сайте.
Одна потенциальная проблема с EAFP заключается в том, что он может скрывать тот факт, что что-то не так с какой-то другой частью вашего кода или стороннего модуля, который вы используете, особенно когда часто возникают исключения (и, следовательно, на самом деле не являются "исключительными" случаями). совсем).
Ответ 4
То, что TypeError
появляется только при попытке передать int()
None
(который является единственным значением NoneType
, насколько я знаю). Я бы сказал, что вашей реальной целью не должно быть преобразование NoneType
в int
или str
, но чтобы выяснить, где/почему вы получаете None
вместо числа, как ожидалось, и либо исправить его, либо правильно отрегулируйте None
.
Ответ 5
Я успешно использовал int (x или 0) для этого типа ошибки, если в логике None должно быть равно 0.
Обратите внимание, что это также решится на 0 в других случаях, когда тестирование x возвращает False. например пустой список, набор, словарь или нулевую длину.
Извините, Киндалл уже дал этот ответ.
Ответ 6
Вы должны проверить, чтобы значение не было None, прежде чем пытаться выполнить какие-либо вычисления на нем:
my_value = None
if my_value is not None:
print int(my_value) / 2
Примечание. my_value
было намеренно установлено значение None, чтобы доказать, что код работает и что проверка выполняется.
Ответ 7
Это может произойти, если вы забыли вернуть значение из функции: оно затем возвращает None. Посмотрите на все места, где вы назначаете эту переменную, и посмотрите, является ли один из них вызовом функции, где функция не имеет оператора return.
Ответ 8
У меня была такая же проблема с использованием функций электронной почты python.
Ниже приведен код, в котором я пытался получить объект электронной почты в переменной. Это отлично подходит для большинства электронных писем, а переменная заполняется. Если вы получили электронное письмо от Yahoo и т.п., И отправитель не заполнил строку темы. Yahoo не создает строку темы в электронном письме и вы получите NoneType, возвращаемый функцией. Мартино дал правильный ответ, а также Совету. Ответ IMO Soviut более краток с точки зрения программирования; не обязательно из Python.
Вот несколько примеров, чтобы показать технику:
import sys, email, email.Utils
afile = open(sys.argv[1], 'r')
m = email.message_from_file(afile)
subject = m["subject"]
# Soviut Concise test for unset variable.
if subject is None:
subject = "[NO SUBJECT]"
# Alternative way to test for No Subject created in email (Thanks for NoneThing Yahoo!)
try:
if len(subject) == 0:
subject = "[NO SUBJECT]"
except TypeError:
subject = "[NO SUBJECT]"
print subject
afile.close()
Ответ 9
В Python 3 вы также можете использовать ключевое слово "или". Сюда:
foo = bar or 0
foo2 = bar or ""
Ответ 10
В некоторых ситуациях полезно иметь функцию для преобразования None в int zero:
def nz(value):
'''
Convert None to int zero else return value.
'''
if value == None:
return 0
return value