Можно ли только объявить переменную без присвоения какого-либо значения в Python? - PullRequest
230 голосов
/ 20 марта 2009

Можно ли объявить переменную в Python, например, так:

var

чтобы оно инициализировалось в None? Кажется, что Python позволяет это, но как только вы получаете к нему доступ, он падает. Это возможно? Если нет, то почему?

РЕДАКТИРОВАТЬ: Я хочу сделать это для случаев, подобных этому:

value

for index in sequence:

   if value == None and conditionMet:
       value = index
       break

Дублирование

Относящиеся

Ответы [ 13 ]

296 голосов
/ 20 марта 2009

Почему бы просто не сделать это:

var = None

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

Это хорошо, потому что у вас никогда не будет неинициализированной переменной. Но будьте осторожны - это не значит, что вы не получите неправильно инициализированных переменных. Если вы инициализируете что-то для None, убедитесь, что это именно то, что вам действительно нужно, и назначьте что-нибудь более значимое, если можете.

54 голосов
/ 20 марта 2009

От всей души рекомендую вам прочитать В других языках есть «переменные» (я добавил его как связанную ссылку) - через две минуты вы узнаете, что в Python есть «имена», а не «переменные» ».

val = None
# ...
if val is None:
   val = any_object
13 голосов
/ 20 марта 2009

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

foo = None

, который присвоит значение None переменной foo.

РЕДАКТИРОВАТЬ: То, что вы действительно , кажется, хотите сделать, это просто:

#note how I don't do *anything* with value here
#we can just start using it right inside the loop

for index in sequence:
   if conditionMet:
       value = index
       break

try:
    doSomething(value)
except NameError:
    print "Didn't find anything"

Сложно сказать, действительно ли это правильный стиль для использования на таком коротком примере кода, но - это более "питонский" способ работы.

РЕДАКТИРОВАТЬ: ниже комментарий JFS (размещен здесь, чтобы показать код)

Не имеет отношения к вопросу ОП, но приведенный выше код можно переписать так:

for item in sequence:
    if some_condition(item): 
       found = True
       break
else: # no break or len(sequence) == 0
    found = False

if found:
   do_something(item)

ПРИМЕЧАНИЕ: если some_condition() вызывает исключение, found не связывается.
ПРИМЕЧАНИЕ: если len (sequence) == 0, то item не связан.

Код выше не рекомендуется. Его цель - проиллюстрировать, как работают локальные переменные, а именно, может ли «переменная» «определяться», может быть определена только во время выполнения в этом случае. Предпочтительный способ:

for item in sequence:
    if some_condition(item):
       do_something(item)
       break

или

found = False
for item in sequence:
    if some_condition(item):
       found = True
       break

if found:
   do_something(item)
10 голосов
/ 09 ноября 2017

В Python 3.6+ вы можете использовать аннотации переменных для этого:

https://www.python.org/dev/peps/pep-0526/#abstract

В PEP 484 введены подсказки типа, аннотации типа a.k.a. Хотя основное внимание было уделено аннотациям функций, оно также вводило понятие комментариев к комментариям для переменных:

# 'captain' is a string (Note: initial value is a problem)
captain = ...  # type: str

PEP 526 направлен на добавление синтаксиса в Python для аннотирования типов переменных (включая переменные класса и переменные экземпляра) вместо их выражения в комментариях:

captain: str  # Note: no initial value!

Кажется, это более точно соответствует тому, что вы спрашивали: «Можно ли только объявить переменную без присвоения какого-либо значения в Python?»

4 голосов
/ 20 марта 2009

Я обычно инициализирую переменную чем-то, что обозначает тип как

var = ""

или

var = 0

Если это будет объект, не инициализируйте его, пока не создадите его экземпляр:

var = Var()
3 голосов
/ 02 ноября 2009

Ну, если вы хотите проверить, определена ли переменная или нет, то почему бы не проверить, находится ли она в массивах locals () или globals ()? Ваш код переписан:

for index in sequence:
   if 'value' not in globals() and conditionMet:
       value = index
       break

Если вы ищете локальную переменную, замените globals () на locals ().

2 голосов
/ 20 марта 2009

Если я правильно понимаю ваш пример, вам не обязательно ссылаться на 'value' в операторе if. Вы выходите из цикла, как только он может быть установлен на что-либо.

value = None
for index in sequence:
   doSomethingHere
   if conditionMet:
       value = index
       break 
2 голосов
/ 20 марта 2009

Прежде всего, мой ответ на первоначально заданный вами вопрос

В: Как я могу определить, определена ли переменная в точке моего кода?

A: Читайте в исходном файле, пока не увидите строку, где определена эта переменная.

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

def findFirstMatch(sequence):
    for value in sequence:
        if matchCondition(value):
            return value

    raise LookupError("Could not find match in sequence")

Очевидно, что в этом примере вы можете заменить raise на return None в зависимости от того, чего вы хотите достичь.

Если вам нужно все, что соответствует условию, вы можете сделать это:

def findAllMatches(sequence):
    matches = []
    for value in sequence:
        if matchCondition(value):
            matches.append(value)

    return matches

Есть еще один способ сделать это с yield, который я не буду вам показывать, потому что он довольно сложен в работе.

Далее, есть один способ добиться этого:

all_matches = [value for value in sequence if matchCondition(value)]
1 голос
/ 16 ноября 2016

Это хороший вопрос и, к сожалению, плохие ответы, так как var = None уже присваивает значение, и если ваш скрипт выполняется несколько раз, он каждый раз перезаписывается None

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

1 голос
/ 20 марта 2009

Похоже, вы пытаетесь написать C на Python. Если вы хотите найти что-то в последовательности, Python имеет встроенные функции для этого, например

value = sequence.index(blarg)
...