Чи можливо лише оголосити змінну без призначення будь-якого значення в Python?


288

Чи можна оголосити змінну в Python, як так ?:

var

щоб він ініціалізувався на None? Схоже, Python дозволяє це, але як тільки ви отримаєте доступ до нього, він виходить з ладу. Чи можливо це? Якщо ні, то чому?

EDIT: Я хочу зробити це для таких випадків:

value

for index in sequence:

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

Дублікат

Пов'язані


1
можна опублікувати невелику програму, яка викликає це, будь ласка.
— Преет Сангха

Ви опублікували повторне запитання, голосуючи за закриття цього питання на користь іншого.
— Єруб

Існує ще деяка різниця, ця стосується того, що не можна використовувати змінну просто шляхом оголошення.
— Джоан Венге

Насправді немає такого поняття, як оголошення змінної у світі python, як пояснюється вашим першим запитанням.
— Харлі Холкомб

1
чому ніхто ніколи не сказав "просто призначити його", тому що змінні не існують до того, як вони будуть призначені до періоду. І змінні в python не містять інформації про тип. Об'єкти роблять це. Змінні призначені лише для утримання об'єкта в цей момент часу. Крім того, програма, наведена вище, повинна викидати виняток NameError у перший рядок. (Ось, що я отримую в 2.X і 3.X обидва)
— osirisgothra

Відповіді:


359

Чому б просто не зробити це:

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 "помилкове", наприклад, нульове або порожнє. Використовуйте isдля перевірки, чи є значення None.
— jfs

Прочитавши статтю за наданим посиланням, це здається трохи більше, ніж семантична софістика.
— Андрій П.

29

У Python 3.6+ ви можете використовувати для цього змінні анотації:

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

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 .

EDIT: Те , що ви на самому справі , здається, потрібно зробити , це просто так:

#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» спосіб роботи.

EDIT: нижче є коментар 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 (послідовність) == 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

Ну, якщо ви хочете перевірити, чи визначена змінна чи ні, то чому б не перевірити, чи є вона у масивах local (()) або глобальних ()? Ваш код переписано:

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

Якщо ви шукаєте локальну змінну, замініть globals () на localals ().


2

Перш за все, моя відповідь на запитання, яке ви спочатку задавали

Питання: Як дізнатись, чи визначена змінна в точці мого коду?

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, якщо ви спробуєте потім використовувати цю змінну у функції. Це може працювати і для дуже давніх версій пітона. Не простий, ані красивий, але від пітона не чекайте багато.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.