У меня есть значение Nonetype
x
, это обычно число, но может быть None
. Я хочу разделить его на число, но Python повышает:
TypeError: int() argument must be a string or a number, not 'NoneType'
Как я могу это решить?
У меня есть значение Nonetype
x
, это обычно число, но может быть None
. Я хочу разделить его на число, но Python повышает:
TypeError: int() argument must be a string or a number, not 'NoneType'
Как я могу это решить?
В одном из комментариев вы говорите:
Как-то я получил значение 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
(если он существует) полностью зависит от цели вашего кода.
int(value or 0)
Это будет использовать 0 в случае, когда вы предоставляете любое значение, которое Python считает False
, например None, 0, [], "" и т.д. Так как 0 False
, вы должны использовать только 0 в качестве альтернативное значение (иначе вы найдете, что ваши 0s превращаются в это значение).
int(0 if value is None else value)
Это заменяет только None
на 0. Поскольку мы специально тестируем None
, вы можете использовать другое значение в качестве замены.
Обычный "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 заключается в том, что он может скрывать тот факт, что что-то не так с какой-то другой частью вашего кода или стороннего модуля, который вы используете, особенно когда часто возникают исключения (и, следовательно, на самом деле не являются "исключительными" случаями). совсем).
То, что TypeError
появляется только при попытке передать int()
None
(который является единственным значением NoneType
, насколько я знаю). Я бы сказал, что вашей реальной целью не должно быть преобразование NoneType
в int
или str
, но чтобы выяснить, где/почему вы получаете None
вместо числа, как ожидалось, и либо исправить его, либо правильно отрегулируйте None
.
Я успешно использовал int (x или 0) для этого типа ошибки, если в логике None должно быть равно 0. Обратите внимание, что это также решится на 0 в других случаях, когда тестирование x возвращает False. например пустой список, набор, словарь или нулевую длину. Извините, Киндалл уже дал этот ответ.
Вы должны проверить, чтобы значение не было None, прежде чем пытаться выполнить какие-либо вычисления на нем:
my_value = None
if my_value is not None:
print int(my_value) / 2
Примечание. my_value
было намеренно установлено значение None, чтобы доказать, что код работает и что проверка выполняется.
Это может произойти, если вы забыли вернуть значение из функции: оно затем возвращает None. Посмотрите на все места, где вы назначаете эту переменную, и посмотрите, является ли один из них вызовом функции, где функция не имеет оператора return.
У меня была такая же проблема с использованием функций электронной почты 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()
В Python 3 вы также можете использовать ключевое слово "или". Сюда:
foo = bar or 0
foo2 = bar or ""
В некоторых ситуациях полезно иметь функцию для преобразования None в int zero:
def nz(value):
'''
Convert None to int zero else return value.
'''
if value == None:
return 0
return value