Python'da herhangi bir değer atamadan sadece bir değişken bildirmek mümkün müdür?


288

Python'da böyle bir değişken bildirmek mümkün mü ?:

var

Hiçbiri? Python buna izin veriyor gibi görünüyor, ancak erişir erişmez çöküyor. Mümkün mü? Değilse, neden?

EDIT: Bunu aşağıdaki gibi durumlar için yapmak istiyorum:

value

for index in sequence:

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

Çiftleme

İlişkili


1
buna neden olan küçük bir program gönderebilir.
Preet Sangha

Yinelenen bir soru yayınladınız ve bu soruyu diğerinin lehine kapatmak için oy verdiniz.
Jerub

Hala bir fark var, bu sadece bir değişkeni bildirerek kullanamamakla ilgilidir.
Joan Venge

İlk sorunuzun açıkladığı gibi, python dünyasında bir değişken bildirmek gibi bir şey yoktur.
Harley Holcombe

1
neden hiç kimse 'sadece atama' demedi çünkü değişkenler döneme atanmadan önce mevcut değildir. Ve python'daki değişkenler tür bilgisi içermiyor. Nesneler bunu yapar. Değişkenler sadece nesneyi o noktada tutmak içindir. Ayrıca, yukarıdaki program ilk satıra bir NameError istisnası atmalıdır. (Hem 2.X hem de
3.X'te aldığım şey

Yanıtlar:


359

Neden sadece bunu yapmıyorsunuz:

var = None

Python dinamiktir, bu yüzden bir şey bildirmeniz gerekmez; atandıkları ilk kapsamda otomatik olarak bulunurlar. Yani, ihtiyacınız olan tek şey yukarıdaki gibi düzenli bir eski atama ifadesidir.

Bu güzel, çünkü asla başlatılmamış bir değişkenle sonuçlanmayacaksınız. Ancak dikkatli olun - bu, yanlış başlatılmış değişkenlerle sonuçlanmayacağınız anlamına gelmez . Bir şey başlatırsanız None, gerçekten istediğiniz şey olduğundan emin olun ve mümkünse daha anlamlı bir şey atayın.


1
Bunu yapacaktım, ama bunu örtük olarak düşündüm.
Joan Venge

7
Mesele, bunun açık olması, örtük olmamasıdır. Başlangıç ​​değerinin ne olduğunu tahmin etmek yok. Başlatılmamış bir değişkenin bir istisna atıp atmadığını veya sihirli bir şekilde faydalı bir değere sahip olup olmadığını merak etmeyin.
S.Lott

2
Bu ile ilgili tek sorun bir sayaç (minValue) takip ediyordu ve her zaman bir değer ondan daha düşüktü, ben yeni minValue olmaya ayarlıyordu. MinValue'yu başlangıçta None olarak bildirirsem, görünüşe göre hala karşılaştırdığım sayılardan daha düşüktür. Ben sadece sys.maxint de başlatmak sona erdi
TJ Biddle

... kendilerine atanan ilk kapsamda otomatik olarak bulunurlar. Yani, ilk ödevi avlamalı ve çözmelisin. öf!
Ed Randall

56

Yürekten tavsiye etmenizi öneririm Diğer dillerin "değişkenleri" (ilgili bir bağlantı olarak ekledim) - iki dakika içinde Python'un "değişkenler" değil, "isimler" olduğunu bilirsiniz.

val = None
# ...
if val is None:
   val = any_object

val = val or any_objectBaşlatmak için de yazabilirsiniz .
Zoltán

1
@ Zoltán: val için geçerli bir değerin "false", örneğin sıfır veya boş olması durumunda kırılır. isBir değerin olup olmadığını test etmek için kullanın None.
jfs

Verilen bağlantıdaki makaleyi okuduktan sonra, anlamsal karmaşıklıktan biraz daha fazlası gibi görünüyor.
Andrew P.

29

Python 3.6+ sürümünde bunun için Değişken Ek Açıklamaları kullanabilirsiniz:

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

PEP 484, tip ek açıklamaları olarak da adlandırıldı. Ana odağı işlev ek açıklamaları iken, ek açıklama değişkenlerine tip açıklamaları kavramını da tanıttı:

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

PEP 526, değişkenler türlerine (sınıf değişkenleri ve örnek değişkenler dahil) açıklama eklemek için yorum yapmak yerine Python'a sözdizimi eklemeyi amaçlamaktadır:

captain: str  # Note: no initial value!

"Python'da herhangi bir değer atamadan yalnızca bir değişken bildirmek mümkün mü?"


2
Mükemmel cevap
Ben

16

Ne yapmaya çalıştığından emin değilim. Python çok dinamik bir dildir; değişkenleri gerçekten atamayana veya kullanana kadar genellikle bildirmeniz gerekmez. Bence yapmak istediğin şey sadece

foo = None

Nonedeğişkene değer atayacaktır foo.

EDIT: Gerçekten yapmak istediğiniz gibi sadece şu:

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

O gerçekten bu kadar kısa kod örneği kullanmak doğru stili olmadığını söylemek biraz zor, ama bir işe daha "Pythonic" yol.

EDIT: aşağıda JFS tarafından yorum (burada kodu göstermek için gönderildi)

OP'nin sorusuyla ilgisi yoktur, ancak yukarıdaki kod şu şekilde yeniden yazılabilir:

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)

NOT: some_condition()bir istisna oluşturursa found, bağlı değildir.
NOT: len (sıra) == 0 itemise bağlı değildir.

Yukarıdaki kod önerilmez. Amacı, yerel değişkenlerin nasıl çalıştığını, yani "değişken" in "tanımlanmış" olup olmadığını sadece bu durumda çalışma zamanında belirlenebildiğini göstermektir. Tercih edilen yolu:

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

Veya

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

if found:
   do_something(item)

Dinamik bir dil ile çok dinamik bir dil arasında bir fark var mı?
Gavin Miller

Programlama dili yazmanın farklı eksenlerini ve bunların boolean değerleri değil nasıl süreklilik olduğunu açıklayan harika bir makale var; ne yazık ki alıntı yapmak istediğimde bu makaleyi bir daha asla bulamıyorum :( Python'u "çok dinamik" olarak görüyorum çünkü birden fazla eksenin en ucunda.
kquinn

3

Genellikle değişkeni türünü gösteren bir şeye başlatırım

var = ""

veya

var = 0

Bir nesne olacaksa, siz başlatana kadar onu başlatmayın:

var = Var()

3

Bir değişkenin tanımlanıp tanımlanmadığını kontrol etmek istiyorsanız, neden bunun locals () veya globals () dizilerinde olup olmadığını kontrol etmiyorsunuz? Kodunuz yeniden yazıldı:

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

Aradığınız yerel bir değişkense globals () öğesini locals () ile değiştirin.


2

Her şeyden önce, aslında sorduğunuz soruya cevabım

S: Bir değişkenin kodumdaki bir noktada tanımlanmış olup olmadığını nasıl anlarım?

C: Değişkenin tanımlandığı bir satır görene kadar kaynak dosyasında okuyun.

Ama ayrıca, bunun oldukça pitonik olan çeşitli permütasyonları olduğuna dair bir kod örneği verdiniz. Bir koşulla eşleşen öğeler için bir dizi taramanın peşindesiniz, işte bazı çözümler:

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

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

Açıkça bu örnekte değiştirmek olabilir raisebir ile return Noneelde etmek istediği bağlı.

Koşulla eşleşen her şeyi istiyorsanız, bunu yapabilirsiniz:

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

    return matches

Bunu yapmanın başka bir yolu daha var, yieldsize göstermekten rahatsız olmayacağım, çünkü çalışma şekli oldukça karmaşık.

Ayrıca, bunu başarmanın tek bir yolu vardır:

all_matches = [value for value in sequence if matchCondition(value)]

2

Örneğin doğru olduğunu anlıyorsam, yine de if ifadesinde 'değer' ifadesine başvurmanıza gerek yoktur. Herhangi bir şeye ayarlanacağı anda döngüden çıkarsınız.

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

1

Python'a C yazmaya çalışıyorsunuz. Bir dizide bir şey bulmak istiyorsanız, Python'un bunu yapmak için yerleşik işlevleri vardır.

value = sequence.index(blarg)

1

Bu iyi bir soru ve ne yazık ki var = Nonezaten bir değer atadığı gibi kötü cevaplar ve senaryonuz birden çok kez çalıştırılırsa Noneher seferinde üzerine yazılır .

Atama olmadan tanımlamakla aynı şey değildir. Hala bu sorunun nasıl atlanacağını anlamaya çalışıyorum.


1

Python'da bir değişken bildirmek mümkün mü (var = Yok):

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

0
var_str = str()
var_int = int()

yaramaz yaramaz yaramaz adam! değişkenler türü ilişkilendirmez, nesneler yapar. var_str, böyle genel bir adla sınırlandırılmamalıdır. Bunu yapacaksanız, örneğin 'var_age' veya 'var_name' gibi anlamlı hale getirin. Bu değerler tamsayılar veya dizgiler ya da ne istersen alınabilir ve python'u diğer dillerden farklı kılan şeyin ruhu olarak nesnelerle değiştirilebilir. Onlar bunu her zaman yapmak zorunda bulursanız, muhtemelen başka bir dil kullanmak istediğinizi söylüyorlar.
osirisgothra

0

Eğer Noneo zaman geçerli bir veri değeridir değişkene Başka bir yol bulmalıyız. Kullanabilirsin:

var = object()

Bu nöbetçi Nick Coghlan tarafından öneriliyor .


0

Bir yorumlayıcıyı bu çirkin oneliner ile kandırabilirsiniz. if None: var = None Başlangıçta değil var, yerel değişken sözlüğüne bir değişken eklemekten başka bir şey yapmaz . Bu değişkeni daha sonra bir işlevde kullanmaya çalışırsanız, yorumlayıcı UnboundLocalError istisnasını atar. Bu çok eski python versiyonları için de işe yarar. Ne basit, ne de güzel, ama python'dan fazla beklemeyin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.