Python оператор условного присваивания - PullRequest
41 голосов
/ 19 июня 2011

Существует ли Python, эквивалентный оператору Ruby ||= («установить переменную, если переменная не задана»)?

Пример в Ruby:

 variable_not_set ||= 'bla bla'
 variable_not_set == 'bla bla'

 variable_set = 'pi pi'
 variable_set ||= 'bla bla'
 variable_set == 'pi pi'

Ответы [ 10 ]

127 голосов
/ 10 июля 2011

Я удивлен, что никто не предложил этот ответ.Он не такой «встроенный», как ||= в Ruby, но в основном он эквивалентен и все еще однострочен:

foo = foo if 'foo' in locals() else 'default'

Конечно, locals() - просто словарьтак что вы можете сделать:

foo = locals().get('foo', 'default')
18 голосов
/ 19 июня 2011

Нет, замена:

try:
   v
except NameError:
   v = 'bla bla'

Однако желание использовать эту конструкцию является признаком чрезмерно сложного потока кода. Обычно вы делаете следующее:

try:
   v = complicated()
except ComplicatedError: # complicated failed
   v = 'fallback value'

и никогда не сомневайтесь, установлен v или нет. Если это один из многих параметров, которые можно либо установить, либо нет, используйте словарь и его метод get, который допускает значение по умолчанию.

13 голосов
/ 13 июля 2012

Я бы использовал

x = 'default' if not x else x

Гораздо короче, чем все ваши альтернативы, предложенные здесь, и прямо к делу. Прочитайте: «установите x в значение« по умолчанию », если x не установлено, в противном случае сохраните его как x». Однако если вам нужны None, 0, False или "" в качестве допустимых значений, вам нужно изменить это поведение, например:

valid_vals = ("", 0, False) # We want None to be the only un-set value

x = 'default' if not x and x not in valid_vals else x

Подобные вещи также просто умоляют превратиться в функцию, которую вы можете легко использовать везде:

setval_if = lambda val: 'default' if not val and val not in valid_vals else val

В этот момент вы можете использовать его как:

>>> x = None # To set it to something not valid
>>> x = setval_if(x) # Using our special function is short and sweet now!
>>> print x # Let's check to make sure our None valued variable actually got set
'default'

Наконец, если вам действительно не хватает нотации Ruby Infix, вы можете перегрузить ||=| (или что-то подобное), следуя хаку этого парня: http://code.activestate.com/recipes/384122-infix-operators/

4 голосов
/ 19 июня 2011

Нет, незнание того, какие переменные определены, является ошибкой, а не функцией Python.

Вместо этого используйте дикты:

d = {}
d.setdefault('key', 1)
d['key'] == 1

d['key'] = 2
d.setdefault('key', 1)
d['key'] == 2
2 голосов
/ 03 декабря 2015

(не могу комментировать, или я бы просто сделал это) Я считаю, что предложение проверить местных жителей выше не совсем верно. Должно быть:

foo = foo if 'foo' in locals() or 'foo' in globals() else 'default'

быть правильным во всех контекстах.

Однако, несмотря на его положительные отзывы, я даже не думаю, что это хороший аналог оператора Ruby. Поскольку оператор Ruby допускает не просто простое имя слева:

foo[12] ||= something
foo.bar ||= something

Метод исключения, вероятно, является ближайшим аналогом.

1 голос
/ 20 октября 2012

В Python 2.5 и более поздних версиях есть условное назначение - синтаксис не очень очевиден, поэтому его легко пропустить Вот как вы это делаете:

x = true_value if condition else false_value

Для дальнейшего ознакомления, ознакомьтесь с документами Python 2.5 .

1 голос
/ 19 июня 2011

Я обычно делаю это следующим образом:

def set_if_not_exists(obj,attr,value):
 if not hasattr(obj,attr): setattr(obj,attr,value)
0 голосов
/ 19 апреля 2017

Я думаю, что вы ищете, если вы ищете что-то в словаре, это метод setdefault:

(Pdb) we=dict()
(Pdb) we.setdefault('e',14)
14
(Pdb) we['e']
14
(Pdb) we['r']="p"
(Pdb) we.setdefault('r','jeff')
'p'
(Pdb) we['r']
'p'
(Pdb) we[e]
*** NameError: name 'e' is not defined
(Pdb) we['e']
14
(Pdb) we['q2']

*** KeyError: 'q2' (Pdb)

В моем примере важно отметить, что метод setdefault изменяет словарь тогда и только тогда, когда отсутствует ключ, на который ссылается метод setdefault.

0 голосов
/ 19 июня 2011

Я не уверен, что правильно понял вопрос здесь ... Попытка «прочитать» значение «неопределенного» имени переменной вызовет NameError. (см. здесь, что у Python есть «имена» , а не переменные ...).

== РЕДАКТИРОВАТЬ ==

Как указано в комментариях delnan, приведенный ниже код не является надежным и во многих ситуациях ломается ...

Тем не менее, если ваша переменная «существует», но имеет какое-то фиктивное значение, например None, будет работать следующее:

>>> my_possibly_None_value = None
>>> myval = my_possibly_None_value or 5
>>> myval
5
>>> my_possibly_None_value = 12
>>> myval = my_possibly_None_value or 5
>>> myval
12
>>> 

(см. этот абзац о значениях истины )

0 голосов
/ 19 июня 2011

Нет, такой ерунды нет.То, что мы не пропустили в Python в течение 20 лет.

...