Можно ли только объявить переменную без присвоения какого-либо значения в 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

Вы также можете написать, 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?»


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)

Есть ли разница между динамическим языком и очень динамичным языком?
— Гэвин Миллер

Есть отличная статья, объясняющая различные оси типизации языка программирования и как они являются континуумами, а не логическими значениями; к сожалению, я никогда не смогу найти эту статью снова, когда захочу процитировать ее :( Я считаю 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 ().


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)]

2

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

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

1

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

value = sequence.index(blarg)

1

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

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


1

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

def decl_var(var=None):
if var is None:
    var = []
var.append(1)
return var

0
var_str = str()
var_int = int()

непослушный непослушный непослушный человек! переменные не связывают тип, объекты делают. var_str не должен ограничиваться таким общим именем. Если вы собираетесь сделать это, сделайте его осмысленным, например, «var_age» или «var_name». Такие значения могут быть приняты как целые числа или строки или как угодно, и могут быть заменены объектами, сам дух того, что отличает Python от других языков. Они говорят, что если вам все время приходится делать это, вы, вероятно, хотите использовать какой-то другой язык.
— osirisgothra

0

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

var = object()

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


0

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.