Python: присвоить значение, если его нет - PullRequest
41 голосов
/ 07 сентября 2011

Я программист RoR, новичок в Python. Я пытаюсь найти синтаксис, который позволит мне установить переменную на определенное значение, только если она не была назначена ранее. В основном я хочу:

# only if var1 has not been previously assigned

var1 = 4

Ответы [ 6 ]

75 голосов
/ 07 сентября 2011

Вы должны инициализировать переменные в None и затем проверить это:

var1 = None
if var1 is None:
    var1 = 4

Который можно записать в одну строку как:

var1 = 4 if var1 is None else var1

или с помощью ярлыка (но проверка на None рекомендуется)

var1 = var1 or 4

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

try:
    var1
except NameError:
    var1 = 4

но я бы советовал против этого.

25 голосов
/ 07 сентября 2011

Это совершенно другой стиль программирования, но я всегда стараюсь переписывать вещи, которые выглядели как

bar = None
if foo():
    bar = "Baz"

if bar is None:
    bar = "Quux"

в просто:

if foo():
    bar = "Baz"
else:
    bar = "Quux"

То есть я стараюсь избегать ситуации, когда некоторые пути кода определяют переменные, а другие - нет. В моем коде никогда не бывает пути, который вызывает неоднозначность набора определенных переменных (на самом деле я обычно делаю еще один шаг и проверяю, что types одинаковы независимо от пути кода) , Это может быть просто вопросом личного вкуса, но я нахожу этот паттерн, хотя и немного менее очевидным, когда пишу его, гораздо легче понять, когда позже читаю его.

24 голосов
/ 30 марта 2014
var1 = var1 or 4

Единственная проблема, с которой это может иметь место, заключается в том, что если var1 является значением Falsey, таким как False или 0 или [], он выберет 4 вместо этого.Это может быть проблемой.

13 голосов
/ 18 апреля 2016

Я тоже из Ruby, поэтому мне нравится синтаксис foo ||= 7.

Это самая близкая вещь, которую я могу найти.

foo = foo if 'foo' in vars() else 7

Я видел, как люди делают этодля dict:

try:
    foo['bar']
except KeyError:
    foo['bar'] = 7

Обновление: Однако я недавно нашел этот драгоценный камень:

foo['bar'] = foo.get('bar', 7)

Если вам это нравится, то для обычной переменной вы могли бысделать что-то вроде этого:

vars()['foo'] = vars().get('foo', 7)
3 голосов
/ 01 июля 2014

Ответ IfLoop (и комментарий MatToufoutu) отлично работает для автономных переменных, но я хотел предоставить ответ всем, кто пытается сделать что-то подобное для отдельных записей в списках, кортежах или словарях.

Словари

existing_dict = {"spam": 1, "eggs": 2}
existing_dict["foo"] = existing_dict["foo"] if "foo" in existing_dict else 3

Возвращает {"spam": 1, "eggs": 2, "foo": 3}

Списки

existing_list = ["spam","eggs"]
existing_list = existing_list if len(existing_list)==3 else 
                existing_list + ["foo"]

Возвращает ["spam", "eggs", "foo"]

Кортежи

existing_tuple = ("spam","eggs")
existing_tuple = existing_tuple if len(existing_tuple)==3 else 
                 existing_tuple + ("foo",)

Возвращает ("spam", "eggs", "foo")

(Не забудьте запятую в ("foo",) для определения «одиночного» кортежа.)

Решение со списками и кортежами будет более сложным, если вы хотите сделать больше, чем просто проверить длину и добавить в конец.Тем не менее, это дает представление о том, что вы можете сделать.

1 голос
/ 07 сентября 2011

Если вы имеете в виду переменную на уровне модуля, то вы можете использовать «глобальные переменные»:

if "var1" not in globals():
    var1 = 4

, но обычная идиома Python - инициализировать ее следующим образом: None (при условии, что она неприемлемазначение), а затем тестирование с if var1 is not None.

...