2010-10-31 3 views
7

Groovy имеет приятный оператор для безопасного разыменования, который помогает избежать NullPointerExceptions:Safe Разыменование в Python

variable?.method() 

method будет называться только, если variable не null.

Есть ли способ сделать то же самое в Python? Или мне нужно написать if variable: variable.method()?

+1

@deamon: во-первых я не знаю, Groovy и я не хочу спорить о том, что я не знаю, но эта функция (после того, как я прочитал об этом сейчас) кажутся мне не полезными (и я могу ошибаться и большую часть времени я), потому что даже если я делаю что-то вроде этого __variable.?method()__ да, конечно, если переменная NULL, это не вызывает ошибку, но как это сделать Я знаю, что метод был вызван, потому что он выглядит для меня как ошибка молчания (на самом деле я никогда не нуждался в чем-то подобном раньше), и если бы я сделал что-то вроде этого __a = variable.?method()__, то после того, как я должен сделать __if (а) __ так ..., я что-то пропустил :) – mouad

+1

Я согласен с сингулярностью; Я не понимаю, как это может быть полезно. Похоже, что вы покроете свой код, чтобы скрыть ошибки. – adw

+0

@ Сет Джонсон: можешь ли ты быть более конкретным, я сказал что-то не так, и если это касается моего английского, это плохо? это не мой первый язык :) – mouad

ответ

10
  1. Нет, не существует.

  2. Но для проверки на None вы не пишите if x:, вы пишете if x is None:. Это важное различие - x оценивает в False уже несколько значений, которые Propably вполне допустимо (в первую очередь 0-эквивалентных чисел и пустых коллекций), в то время как x is Noneтолько вычисляет True если ссылочных x указывает на объект одноплодной None ,

  3. Из личного опыта такой оператор понадобится очень редко. Да, None иногда используется для указания значения. Но почему-то - может быть, потому, что идиоматический код возвращает null objects, где разумные или бросает исключения, чтобы указать критический сбой - я получаю только AttributeError: 'NoneType' object has no attribute '...' два раза в месяц.

  4. Я бы сказал, что это может быть неправильной работой. null имеет два значения - «забыл инициализировать» и «нет данных». Первый является ошибкой и должен вызывать исключение. Второй случай обычно требует более сложной обработки, чем «давайте просто не будем называть этот метод». Когда я спрашиваю базу данных/ORM для UserProfile, ее там нет, и я получаю null вместо этого ... я хочу тихо пропустить оставшуюся часть метода? Или я действительно хочу (когда в «библиотечном коде») выбросить соответствующее исключение (так что «пользователь (код)» знает, что пользователь не существует и может реагировать ... или игнорировать его) или (когда я кодирование определенной функции) показать разумное сообщение («Этот пользователь не существует, вы не можете добавить его в список друзей») пользователю?

3

У Python такой вещи нет. Это связано с тем, что в Python нет указателя null. Ну, есть специальное значение None, которое часто используется в ситуациях, когда оно представляет «нет значения». Но это всего лишь конвенция. None - это значение/объект, как и все остальные. А так как нет null, у оператора нет оператора.

+1

Я согласен, но «Нет» по сути то же самое в этом случае. Вместо «NullPointerException» я получил бы атрибут «AttributeError», но не смог вызвать метод «Нет», который будет присутствовать в обычном объекте, таком как список. – deamon

+1

Дело в том, что 'None' вовсе не является« необычным ». Это объект с соответствующим классом, имеет методы и т. Д. На языке, который бы сделал его особенным, нет ничего (кроме того, что он используется для представления значения «ничего интересного здесь»).Итак, что бы проверить гипотетический оператор?? .'? Для 'Нет' конкретно? Что относительно других библиотек, которые используют другие маркеры (например, 'NOT_FOUND' в PEAK)? – Dirk

+2

'None' отлично подходит для маркировки необязательных аргументов функции и других вещей, но их следует использовать (или что-то вроде' NOT_FOUND') как результат «не найден» или другое специальное возвращаемое значение. Использование исключений для этих видов исключительных условий лучше, потому что оно упрощает код с помощью этих функций (вместо проверки каждого возвращаемого значения вы можете иметь предложение except или просто разрешить исключение пузыря). – adw

3

Идиома Я видел и использовал на месте вызова обычной функции (где возвращаемое значение не используется) callable(func) and func(a, b, c). Однако, если вы пытаетесь использовать возвращаемое значение, эта идиома даст False, если функция не может быть вызвана, что может и не быть тем, что вы хотите. В этом случае вы можете использовать тернарный оператор для подачи значения по умолчанию. Например, если функция вернет список, который вы перечислили бы, вы можете использовать пустой список как значение по умолчанию с func(a, b, c) if callable(func) else [].

2

Я использовал эту функцию в Groovy, поэтому я не буду повторять парадокс blub других плакатов.

В Groovy заявление как этот

if(possiblyNull?.value){ 
    ... 

ли это в Python

try: 
    testVar = possiblyNull.value 
except: 
    testVar = None 
if(testVar): 

Это, безусловно, интересная особенность в Groovy, и полезно в устранении синтаксической шума. Есть еще несколько битов синтаксического сахара, таких как оператор Элвиса или *, но они приносят в жертву разборчивость в качестве расхода для быстрого исправления символов (другими словами, они не являются питонами).

Надежда, что помогает :-)

Смежные вопросы