Чи можливо лише оголосити змінну без призначення будь-якого значення в 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.