Pythoni c способ присвоения значения переменной, если оператор не вызывает исключение - PullRequest
0 голосов
/ 27 марта 2020

Я хотел бы присвоить значение переменной, если определенный оператор не вызывает исключений. Если возникают исключения, следует назначить None. Как Pythoni c способ достичь этого?

Вот конкретный пример того, что я пытаюсь сделать:

try:
    bar = foo(data['buzz']) # data is a dict
except KeyError:
    bar = None

Примечания:

  • KeyError может произойти из-за того, что buzz не существует в data
  • foo все еще может выдать исключение (любого типа, зависит от его реализации), даже если buzz существует в data

Ответы [ 6 ]

2 голосов
/ 27 марта 2020

Пока ваш подход читабелен, вы можете рассмотреть следующее:

Предупреждение?

bar будет установлено на None, если KeyError также встречается внутри функции:

data = {'buzz': 1}

def foo(x):
    abc_value = <b>data['abc']</b> # this raises a `KeyError` inside function `foo`.

try:
    bar = foo(data['buzz']) # data is a dict
except KeyError:
    bar = None

print(bar)
# None

Решение:

Лучший способ избежать этого - избегать использования try-except, поскольку его область также вложена :

if "buzz" in data:
    bar = foo(data["buzz"])
else:
    bar = None

Еще больше питонически в одну строку:

bar = foo(data["buzz"]) if "buzz" in data else None 
1 голос
/ 27 марта 2020

Для полноты, другим способом избежать проблемы, поднятой Остином, с другими KeyError с в foo (не вызванными отсутствием "buzz" в data), инициирующими предложение except, было бы используйте предложение else:

try:
    val = data["buzz"]
except KeyError:
    bar = None
else:
    bar = foo(val)

Это предложение else будет выполнено в том случае, если операторы внутри try не вызовут KeyError.

Конечно, в этом случае вам лучше явно проверить, существует ли в словаре ключ "buzz", как предлагали другие.

0 голосов
/ 27 марта 2020

Предполагая, что foo не вызывает ключевую ошибку:

bar = foo(data['buzz']) if 'buzz' in data else None

Однако, я думаю, что ваш подход более чистый и правильный, основанный на шаблоне pythoni c "просить прощения, а не разрешение "описано здесь: https://docs.quantifiedcode.com/python-anti-patterns/readability/asking_for_permission_instead_of_forgiveness_when_working_with_files.html

0 голосов
/ 27 марта 2020
bar = [f if 'buzz' in data else None for f in data][0]  

[0] часть не так pythoni c, как я хотел бы ...

0 голосов
/ 27 марта 2020

Если вы специально спрашиваете о словаре, вы можете использовать myDic.get(key) вместо myDict(key), почему? поскольку get() предоставляет значение fallback, каков запасной вариант? если key не в myDict, используйте запасное значение, в вашем случае:

bar = foo(data.get('buzz', None) # if buzz is in data, return data["buzz"] else None
0 голосов
/ 27 марта 2020

Я думаю, что лучший способ сделать это в вашем примере:

if "buzz" in data:
    bar = foo(data["buzz"])
else:
    bar = None
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...