Czy możliwe jest jedynie zadeklarowanie zmiennej bez przypisywania żadnej wartości w Pythonie?

288

Czy w Pythonie można zadeklarować zmienną ?:

var

tak, że został zainicjowany na Brak? Wygląda na to, że Python na to pozwala, ale gdy tylko uzyskasz do niego dostęp, ulega awarii. czy to możliwe? Jeśli nie to dlaczego?

EDYCJA: Chcę to zrobić dla takich przypadków:

value

for index in sequence:

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

Duplikować

Związane z

Joan Venge
źródło
1
może opublikować mały program, który to powoduje.
Preet Sangha
Wysłałeś duplikat pytania, głosując za jego zamknięciem na korzyść drugiego.
Jerub
Nadal istnieje pewna różnica, ta dotyczy braku możliwości użycia zmiennej tylko przez zadeklarowanie.
Joan Venge
Tak naprawdę nie ma czegoś takiego jak deklarowanie zmiennej w świecie python, jak wyjaśnia twoje pierwsze pytanie.
Harley Holcombe
1
dlaczego nikt nigdy nie powiedział „po prostu przypisuj to”, ponieważ zmienne nie istnieją przed przypisaniem do kropki. A zmienne w pythonie nie zawierają informacji o typie. Obiekty to robią. Zmienne służą tylko do trzymania obiektu w tym momencie. Ponadto powyższy program powinien zgłosić wyjątek NameError w pierwszym wierszu. (To, co dostaję w obu
wersjach

Odpowiedzi:

359

Dlaczego po prostu tego nie zrobić:

var = None

Python jest dynamiczny, więc nie musisz deklarować rzeczy; istnieją automatycznie w pierwszym zakresie, do którego zostały przypisane. Wszystko, czego potrzebujesz, to zwykłe stare oświadczenie o przydziale, jak wyżej.

To miłe, ponieważ nigdy nie skończysz z niezainicjowaną zmienną. Ale bądź ostrożny - to nie znaczy, że nie skończysz z niepoprawnie zainicjowanymi zmiennymi. Jeśli coś zainicjujesz None, upewnij się, że tego naprawdę chcesz i przypisz coś bardziej znaczącego, jeśli możesz.

Todd Gamblin
źródło
1
Miałem to zrobić, ale po prostu domyślałem się, że tak się stanie.
Joan Venge
7
Chodzi o to, aby było to jawne, a nie dorozumiane. Bez zgadywania, jaka jest wartość początkowa. Nic dziwnego, że niezainicjowana zmienna zgłasza wyjątek lub magicznie ma przydatną wartość.
S.Lott,
2
Jedyny problem, jaki mi z tym wynikał, to to, że śledziłem licznik (minValue) i za każdym razem, gdy wartość była niższa, ustawiałem go, aby stał się nowym minValue. Jeśli pierwotnie zadeklarowałem minValue jako None, to najwyraźniej jest on nadal niższy niż dowolne liczby, z którymi go porównałem. Skończyłem właśnie inicjowanie go na sys.maxint
TJ Biddle
... istnieją automatycznie w pierwszym zakresie, do którego zostały przypisane. Musisz więc odszukać to pierwsze zadanie i je rozgryźć. fuj!
Ed Randall,
56

Serdecznie polecam przeczytanie Inne języki mają „zmienne” (dodałem je jako powiązany link) - za dwie minuty dowiesz się, że Python ma „nazwy”, a nie „zmienne”.

val = None
# ...
if val is None:
   val = any_object
jfs
źródło
Możesz także napisać, val = val or any_objectaby go zainicjować.
Zoltán,
1
@ Zoltán: psuje się, jeśli poprawna wartość dla val jest „false”, np. Zero lub pusta. Służy isdo testowania, czy wartość jest None.
jfs
Po przeczytaniu artykułu pod dostarczonym linkiem wydaje się, że jest to coś więcej niż sofistyka semantyczna.
Andrew P.,
29

W Pythonie 3.6+ możesz użyć do tego Zmiennych Adnotacji:

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

PEP 484 wprowadził podpowiedzi typu, czyli adnotacje typu. Chociaż głównym celem były adnotacje funkcyjne, wprowadzono również pojęcie komentarzy typu do adnotacji zmiennych:

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

PEP 526 ma na celu dodanie składni do Pythona w celu opisywania typów zmiennych (w tym zmiennych klas i zmiennych instancji), zamiast wyrażania ich poprzez komentarze:

captain: str  # Note: no initial value!

Wydaje się, że jest to bardziej zgodne z tym, o co pytasz: „Czy można jedynie zadeklarować zmienną bez przypisywania żadnej wartości w Pythonie?”

Tagar
źródło
2
Doskonała odpowiedź
Ben
16

Nie jestem pewien, co próbujesz zrobić. Python jest bardzo dynamicznym językiem; zwykle nie musisz deklarować zmiennych, dopóki nie zamierzasz ich przypisać lub użyć. Myślę, że to, co chcesz zrobić, jest po prostu

foo = None

który przypisze wartość Nonedo zmiennej foo.

EDYCJA: Wydaje się, że naprawdę chcesz to zrobić:

#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"

Trochę trudno jest stwierdzić, czy to naprawdę odpowiedni styl do użycia z takiego krótkiego przykładu kodu, ale jest to bardziej „Pythoński” sposób pracy.

EDYCJA: poniżej jest komentarz JFS (opublikowany tutaj, aby pokazać kod)

Nie ma związku z pytaniem PO, ale powyższy kod można przepisać jako:

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)

UWAGA: jeśli some_condition()podniesiony zostanie wyjątek, wówczas nie foundjest związany.
UWAGA: jeśli len (sekwencja) == 0, to itemjest niezwiązane.

Powyższy kod nie jest wskazany. Jego celem jest zilustrowanie działania zmiennych lokalnych, a mianowicie, czy „zmienna” jest „zdefiniowana”, w tym przypadku można ją określić tylko w czasie wykonywania. Preferowany sposób:

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

Lub

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

if found:
   do_something(item)
Kquinn
źródło
Czy istnieje różnica między językiem dynamicznym a językiem bardzo dynamicznym?
Gavin Miller
Jest świetny artykuł wyjaśniający różne osie pisania języka programowania oraz sposób, w jaki są one kontinuum, a nie wartościami logicznymi; niestety, nigdy więcej nie mogę znaleźć tego artykułu, gdy chcę go zacytować :( Uważam, że Python jest „bardzo dynamiczny”, ponieważ znajduje się na drugim końcu wielu osi.
kquinn
3

Zazwyczaj inicjuję zmienną do czegoś, co oznacza typ

var = ""

lub

var = 0

Jeśli będzie to obiekt, nie inicjuj go, dopóki go nie utworzysz:

var = Var()
Andrew Hare
źródło
3

Cóż, jeśli chcesz sprawdzić, czy zmienna jest zdefiniowana, czy nie, to dlaczego nie sprawdzić, czy jest ona w tablicach locals () czy globals ()? Twój kod został przepisany:

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

Jeśli szukasz zmiennej lokalnej, zamień globals () na locals ().

Johan
źródło
2

Przede wszystkim moja odpowiedź na pierwotnie zadane pytanie

P: Jak mogę sprawdzić, czy zmienna jest zdefiniowana w pewnym punkcie mojego kodu?

Odp .: Czytaj w pliku źródłowym, aż zobaczysz linię, w której ta zmienna jest zdefiniowana.

Ale podałeś przykład kodu, że istnieją różne permutacje, które są dość pytoniczne. Poszukujesz sposobu na skanowanie sekwencji w poszukiwaniu elementów pasujących do warunków, więc oto kilka rozwiązań:

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

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

Najwyraźniej w tym przykładzie możesz zamienić na raisew return Nonezależności od tego, co chcesz osiągnąć.

Jeśli chcesz wszystkiego, co odpowiada warunkowi, możesz to zrobić:

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

    return matches

Jest inny sposób na zrobienie tego z yieldtym, że nie zawracam ci głowy pokazaniem, ponieważ jest to dość skomplikowane w działaniu.

Ponadto istnieje jeden liniowy sposób osiągnięcia tego:

all_matches = [value for value in sequence if matchCondition(value)]
Jerub
źródło
2

Jeśli dobrze rozumiem twój przykład, nie musisz odwoływać się do „wartości” w instrukcji if. Zrywasz się z pętli, gdy tylko można to ustawić na cokolwiek.

value = None
for index in sequence:
   doSomethingHere
   if conditionMet:
       value = index
       break 
Fholo
źródło
1

Wyglądasz, jakbyś próbował napisać C w Pythonie. Jeśli chcesz znaleźć coś w sekwencji, Python ma wbudowane funkcje, aby to zrobić, na przykład

value = sequence.index(blarg)

źródło
1

To dobre pytanie i niestety złe odpowiedzi, ponieważ var = Nonejuż przypisuje wartość, a jeśli skrypt uruchamia się wiele razy, za Nonekażdym razem jest zastępowany .

To nie to samo, co definiowanie bez przypisania. Wciąż próbuję wymyślić, jak obejść ten problem.

zinturis
źródło
1

Czy można zadeklarować zmienną w Pythonie (var = None):

def decl_var(var=None):
if var is None:
    var = []
var.append(1)
return var
Abderrahim
źródło
0
var_str = str()
var_int = int()
Zaur
źródło
niegrzeczny niegrzeczny niegrzeczny człowiek! zmienne nie kojarzą typu, a obiekty. var_str nie powinno być ograniczone w tak ogólnej nazwie. Jeśli zamierzasz to zrobić, nadaj mu sens, na przykład „var_age” lub „var_name”. Takie wartości można przyjmować jako liczby całkowite lub ciągi znaków lub dowolne, i zamieniać na obiekty, co jest duchem tego, co odróżnia Pythona od innych języków. Mówią, że jeśli musisz to robić cały czas, prawdopodobnie chcesz używać innego języka.
osirisgothra
0

Jeśli Nonejest to poprawna wartość danych, musisz zmienić zmienną w inny sposób. Możesz użyć:

var = object()

Ten wartownik jest sugerowany przez Nicka Coghlana .

Chris_Rands
źródło
0

Za pomocą tego brzydkiego onelinera można oszukać interpretera. if None: var = None Nie robi on nic poza dodawaniem zmiennej vardo lokalnego słownika zmiennych, a nie inicjowaniem jej. Interpreter zgłosi wyjątek UnboundLocalError, jeśli spróbujesz później użyć tej zmiennej w funkcji. Działa to również w przypadku bardzo starożytnych wersji Pythona. Nie jest to ani proste, ani piękne, ale nie oczekuj wiele od Pythona.

ZAB
źródło