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

289

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

var

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

РЕДАКТИРОВАТЬ: Я хочу сделать это для таких случаев, как это:

value

for index in sequence:

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

Дублированный

Связанный

Джоан Венге
источник
1
Можно опубликовать небольшую программу, которая вызывает это, пожалуйста.
Прит Сангха
Вы опубликовали дубликат вопроса, проголосовав, чтобы закрыть этот вопрос в пользу другого.
Иеруб,
Есть еще некоторое различие, это касается неспособности использовать переменную только путем объявления.
Джоан Венге
На самом деле в мире питонов нет такой вещи, как объявление переменной, как объясняет ваш первый вопрос.
Харли Холкомб
1
почему никто никогда не говорил «просто назначить ему», потому что переменные не существуют до того, как они назначены на период. И переменные в python не содержат информацию о типе. Объекты делают это. Переменные предназначены только для удержания объекта в данный момент времени. Кроме того, вышеприведенная программа должна выдать исключение NameError в первой строке. (Это то, что я получаю в 2.X и 3.X оба)
osirisgothra

Ответы:

361

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

var = None

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

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

Тодд Гамблин
источник
1
Я собирался сделать это, но просто подумал, что это сделает это.
Джоан Венге
7
Дело в том, чтобы это было явным, а не неявным. Не догадываясь, каково начальное значение. Неудивительно, что неинициализированная переменная генерирует исключение или имеет магическое значение.
S.Lott
2
Единственная проблема с этим состояла в том, что я отслеживал счетчик (minValue), и всякий раз, когда значение было ниже его, я устанавливал его, чтобы он стал новым minValue. Если я первоначально объявил minValue как None, то, очевидно, он все еще ниже, чем любые числа, с которыми я сравнивал. Я просто инициализировал его в sys.maxint
TJ Biddle
... они автоматически существуют в первой области видимости, где они назначены. Итак, вы должны выследить это первое задание и выяснить это. тьфу!
Эд Рэндалл
56

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

val = None
# ...
if val is None:
   val = any_object
JFS
источник
Вы также можете написать, val = val or any_objectчтобы инициализировать его.
Золтан
1
@ Zoltán: он ломается, если допустимое значение для val равно «false», например, ноль или пусто. Используйте, isчтобы проверить, является ли значение None.
JFS
После прочтения статьи по предоставленной ссылке она кажется немного больше, чем семантическая софистика.
Андрей П.
29

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

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

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

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

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

captain: str  # Note: no initial value!

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

Tagar
источник
2
Отличный ответ
Бен
16

Я не уверен, что ты пытаешься сделать. 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"

Это немного трудно сказать , если это действительно правильный стиль для использования с такой короткий пример кода, но это более «Pythonic» способ работы.

РЕДАКТИРОВАТЬ: ниже комментарий 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)
kquinn
источник
Есть ли разница между динамическим языком и очень динамичным языком?
Гэвин Миллер
Есть отличная статья, объясняющая различные оси типизации языка программирования и как они являются континуумами, а не логическими значениями; к сожалению, я никогда не смогу найти эту статью снова, когда захочу процитировать ее :( Я считаю Python «очень динамичным», потому что он находится на дальнем конце нескольких осей.
kquinn
3

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

var = ""

или

var = 0

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

var = Var()
Эндрю Хэйр
источник
3

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

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

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

Johan
источник
2

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

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

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)]
Jerub
источник
2

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

value = None
for index in sequence:
   doSomethingHere
   if conditionMet:
       value = index
       break 
fholo
источник
1

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

value = sequence.index(blarg)

источник
1

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

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

zinturis
источник
1

Можно ли объявить переменную в Python (var = None):

def decl_var(var=None):
if var is None:
    var = []
var.append(1)
return var
Abderrahim
источник
0
var_str = str()
var_int = int()
Заур
источник
непослушный непослушный непослушный человек! переменные не связывают тип, объекты делают. var_str не должен ограничиваться таким общим именем. Если вы собираетесь сделать это, сделайте его осмысленным, например, «var_age» или «var_name». Такие значения могут быть приняты как целые числа или строки или как угодно, и могут быть заменены объектами, сам дух того, что отличает Python от других языков. Они говорят, что если вам все время приходится делать это, вы, вероятно, хотите использовать какой-то другой язык.
osirisgothra
0

Если Noneдопустимое значение данных, то вам нужно изменить переменную другим способом. Вы можете использовать:

var = object()

Этот страж предлагается Ником Когланом .

Chris_Rands
источник
0

Вы можете обмануть интерпретатора этим уродливым oneliner. if None: var = None Он ничего не делает, кроме добавления переменной varв словарь локальных переменных, а не ее инициализации. Интерпретатор сгенерирует исключение UnboundLocalError, если вы попытаетесь впоследствии использовать эту переменную в функции. Это будет работать и для очень древних версий Python. Не простой и не красивый, но не ожидайте многого от питона.

ЗАБ
источник