Каков самый питоновский способ предоставить значение возврата в задании?

В Perl часто бывает полезно назначить объект, но указать некоторое значение возврата, если назначаемая переменная имеет значение "undef". Например:

my $x = undef;
my $y = 2;
my $a = $x || $y;

После этого

$a == 2

Есть ли сжатый способ достичь этого в Python, если значение x равно None или будет полнофункциональным...

if x is not None
    a = x
else
    a = y

... быть самым путинским способом достижения этого?

EDIT: Извинения, как было отмечено несколькими комментаторами, я действительно не говорил о ценности undefined, но "undef" в Perl, что на самом деле не то же самое. Но вопрос, как изначально сформулированный, не сделал этого ясно.

Ответы

Ответ 1

Так как 2.5:

Если вы хотите вернуться только в None:

a = x if x is not None else y 

Если вы хотите отступить также на пустую строку, false, 0 и т.д.:

a = x if x else y 

или

a = x or y 

Что касается undefined (как никогда не определено, a.k.a. не связано):

try:
  a = x 
except NameError:
  a = y

или немного более хакерский (я бы не рекомендовал этого, но он был коротким):

a = vars().get('x',y)

Ответ 2

сначала вы можете сделать свой полный вход с тройным:

a = y if x is None else x

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

try:
    a = x
except:
    a = y

Ответ 3

Просто несколько примеров с примером Perl:

my $x = undef;

Этот избыточный код можно сократить до:

my $x;

И следующий код не делает то, что вы говорите:

my $a = $x || $y;

Это фактически присваивает $y $$ при $x false. Ложные значения включают такие вещи, как undef, ноль и пустая строка. Чтобы проверить только определенность, вы можете сделать следующее (начиная с Perl 5.10):

my $a = $x // $y;

Ответ 4

Я вполне убежден, что нет никакого "пуфонического" способа сделать это, потому что это не шаблон, который является питоном. Элемент управления не должен достигать ссылки undefined в элегантном коде. Есть похожие идеи, которые являются питонами. Наиболее очевидно:

def myRange(start, stop=None):
    start, stop = (0, start) if stop is None else (start, stop)
    ...

Что важно, что stop определяется в области видимости, но вызывающему не нужно было передавать его явно, только чтобы оно приняло это значение по умолчанию, изменив семантику аргументов, что фактически вызывает первый аргумент быть необязательным, а не вторым, даже если язык не позволяет этого без этого умного трюка.

Как говорится, что-то вроде этого может следовать за помещением без использования блока try-catch.

a = locals().get('x', y)

Ответ 5

Тройная операция python:

a = x if x is not None else y

Доступно в версии 2.5 и выше.

Ответ 7

Большинство решений, основанных на операторах if, не работают для случая, когда x равно 0 или отрицательному.

>>> x = 0
>>> y = 2
>>> a = x or y
>>> a
2
>>> 

Если вы знали имя переменной раньше времени, вы могли бы выглядеть так:

if 'x' in dir():
    a = x 
except:
     a =y

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

try:
    a = x
else:
    a = y

Ответ 8

Один способ переписать...

if x is not None
    a = x
else
    a = y

.. есть:

x = myfunction()

if x is None:
    x = y

print x

Или, используя исключения (возможно, больше Python'ы, в зависимости от того, что делает код - если он возвращает None, потому что произошла ошибка, использование исключения, вероятно, является правильным способом):

try:
    x = myfunction()
except AnException:
    x = "fallback"

print x

Все, что сказал, действительно нет ничего плохого в вашем исходном коде:

if x is not None
    a = x
else
    a = y

Это долго, но я нахожу, что гораздо легче читать (и многое другое Pythonic), чем любой из следующих однострочных:

a = x if x is not None else y
a = x or y

Ответ 9

Если это аргумент функции, вы можете сделать это:

def MyFunc( a=2 ):
    print "a is %d"%a

>>> MyFunc()
...a is 2
>>> MyFunc(5)
...a is 5

[Изменить] Для downvoters.. бит if/else не нужен для решения - просто добавлен, чтобы сделать результаты ясными. Отредактировано это, чтобы удалить оператор if, если это делает его более понятным?