Bir değişkenin olup olmadığını nasıl kontrol ederim?


953

Bir değişken olup olmadığını kontrol etmek istiyorum. Şimdi böyle bir şey yapıyorum:

try:
   myVar
except NameError:
   # Do something.

İstisnasız başka yollar var mı?


15
İstisnada yanlış olan ne?
S.Lott

10
@ S.Lott: myVarGerçekten karmaşık bir şey varsa , üretilmesi / değerlendirilmesi uzun zaman alırsa , tryyavaş şeyler yavaş olmaz mı?
dbliss

3
@dbliss: Bu bir değişken. Gerçekten garip vakaların yanı sıra, çılgın bir şey execya da metasınıflar yapıyorsanız , pahalı olmayacaktır.
user2357112 Monica

Yanıtlar:


1627

Yerel bir değişkenin varlığını kontrol etmek için:

if 'myVar' in locals():
  # myVar exists.

Genel bir değişkenin varlığını kontrol etmek için:

if 'myVar' in globals():
  # myVar exists.

Bir nesnenin özniteliği olup olmadığını kontrol etmek için:

if hasattr(obj, 'attr_name'):
  # obj.attr_name exists.

29
Tamam, sınıfta var olan özniteliği nasıl kontrol edebilirim?
Max Frai

7
ve muhtemelen var olmayan değişkenin adını bir dizeye nasıl dönüştürürsünüz?
SilentGhost

15
Ancak OP kodu yazıyor, myVar'ın 'myVar' intstead yazabilirler. Kod yazılırken değişken adı bilinmiyorsa, çalışma zamanında bir dize değişkeninde saklanır ve postaladığım çek de çalışır.
Ayman Hourieh

8
Ayrıca yerleşik değişkenler ve iç içe geçmiş işlevleriniz varsa dış kapsamlardaki değişkenler de vardır. Hepsini kontrol etmek istiyorsanız, muhtemelen en iyisi tetiklemektir NameError.
Petr Viktorin

14
if hasattr(obj, 'attr_name'):Sınıflar için de en iyisini sevdim : ieif hasattr(self, 'attr_name'):
Ron Kalian

118

Kullanım tanımlı veya (örtülü veya açık) ayarlanan edilmiş henüz değişkenlerin hemen her zaman kötü bir şeydir herhangi genellikle programın mantığı doğru düzgün düşünce edilmediğini gösterir ve sonuç muhtemel olduğundan, dil öngörülemeyen davranışlarda.

Python'da yapmanız gerekiyorsa , sizinkine benzer aşağıdaki hile, bir değişkenin kullanımdan önce bazı değerlere sahip olmasını sağlayacaktır :

try:
    myVar
except NameError:
    myVar = None

# Now you're free to use myVar without Python complaining.

Ancak, hala iyi bir fikir olduğuna ikna olmadım - bence, bu durumun ortaya çıkmaması için kodunuzu yeniden düzenlemeye çalışmalısınız.


8
Belki bir bağımlılık değişkenidir ve var olabileceği veya bulunmayabileceği sürüme / platforma göre ve hangi sürümün olduğunu bilmenin başka bir yolu yoktur.
WhyNotHugo

35
Durum değişkenleri atanmadan önce mevcut değildir - bir önceki konumdan geçerli konuma bir çizgi çizerseniz, önceki = akım değerini ayarlarsanız, ilk çağrıda "değişkenlerinizi bilmediğiniz" anlamına gelmez. Ve önceki = null çizim yordamının dışında başlatmak için fazladan bir kod satırı yazmak, "değişkenlerinizi bildiğiniz" anlamına gelmez.
Dave

4
Demek istediğim, bir blok "son ise: draw (son, akım); son = akım" 'ın anlaşılması kolay ve zayıf programlama değil. Test etmeden önce "son" olup olmadığını kontrol etmek için bir "dene / hariç" eklemek, bu kodun okunabilirliğini azaltır.
Dave

23
"Tanımlanmamış değişkenlerin kullanımı aslında herhangi bir dilde kötü bir şeydir" Bana küçümseyen konuşmayı koru. Bazılarımız Python'u Matlab gibi çalışan Spyder gibi IDE'leri kullanan basit matematik veya istatistik komut dosyaları için kullanıyoruz. Bazen bu ortamlarda, kullanıcının genel konsoldaki değişkenleri tanımlamasına ve Matlab'da matematik yaparken olduğu gibi komut dosyasında bildirilmemiş olup olmadığını kontrol etmesine izin vermek mantıklıdır.
Ricardo Cruz

15
En azından için @Ricardo, belki daha ziyade 's tenezzülü varsayarak yerine, isteyebilirsiniz düşünün olasılığını da birinden sadece iyi bir öğüt olduğunu olabilir daha bilgili olmak :-) Yoksa ben küresel kısıtlanmamış kullanımına karşı tavsiye eğer eşit patronluk düşünürdünüz değişkenler, spagetti kodu, tanrı nesneleri, denenmemiş kod yayınlama veya COBOL işletim sistemleri yazma? Cevabım, bunun neden kötü bir fikir olduğunu düşündüğümü belirtti (ve soruda OP'nin neden gerekli olduğunu düşündüğünü gösteren hiçbir şey yoktu), ancak yine de gerçekten yapmak istedikleri şansa bir yol sağladı.
paxdiablo

52

Basit bir yol, ilk başta myVar = None

Sonra daha sonra:

if myVar is not None:
    # Do something

2
Bu cevapta geliştirilecek çok şey var. Aksine - Basit bir yol önce bildirmektir. myVar = none # do stuff... if not myVar: # give myVar a value myVar = 'something'
Shawn Mehan

Ben bunu bir çok seviyorum çünkü benim exceptifadelerde Hiçbiri şeyler ayarlayın
HashRocketSyntax

neden böyle bir şey değil: if myVar: # Do something Bu bir çift negatif okuma ihtiyacını ortadan kaldırır
jjisnow

@jjisnow myVarBoş bir liste, sıfır, boş dize vb. olsa bile bu koşulun doğru olmasını istiyorsunuz .
Gabriel

7
@Var bildirilmezse @jjisnow python3'e if myVar: # Do somethingatıyorNameError
Agile Bean

25

Try / hariç kullanımı bir değişkenin varlığını test etmenin en iyi yoludur. Ancak, küresel değişkenleri ayarlamak / test etmek yerine, yaptığınız her şeyi yapmanın neredeyse daha iyi bir yolu vardır.

Örneğin, bir işlevi ilk çağırdığınızda modül düzeyindeki bir değişkeni başlatmak istiyorsanız, şöyle bir kodla daha iyi durumda olursunuz:

my_variable = None

def InitMyVariable():
  global my_variable
  if my_variable is None:
    my_variable = ...

2
Bunu kullanmamaya çalışıyorum çünkü global isim alanını kirletiyor. Bundan kaçınmanın bir yolu, my_variable'ı bir sınıf değişkeni ile fonksiyonu bir sınıf haline getirmek ve çağrıyı mevcut fonksiyonun gövdesi olarak tanımlamaktır , ancak bu bir kodlama acısıdır ve bir dizi başka soru açar. İşlev niteliklerini kullanmayı tercih ederim, aşağıya bakın.
samwyse

17

nesneler / modüller için ayrıca

'var' in dir(obj)

Örneğin,

>>> class Something(object):
...     pass
...
>>> c = Something()
>>> c.a = 1
>>> 'a' in dir(c)
True
>>> 'b' in dir(c)
False

11

Testin user97370'in cevabına benzer bir fonksiyonda kullanılacağını varsayacağım . Bu yanıtı sevmiyorum çünkü küresel isim alanını kirletiyor. Bunu düzeltmenin bir yolu bunun yerine bir sınıf kullanmaktır:

class InitMyVariable(object):
  my_variable = None

def __call__(self):
  if self.my_variable is None:
   self.my_variable = ...

Bunu sevmiyorum, çünkü kodu karmaşıklaştırıyor ve bu gibi soruları açıyor, bu Singleton programlama modeline onaylamalı mı? Neyse ki, Python işlevlerin bir süre niteliklere sahip olmasına izin verdi, bu da bize bu basit çözümü veriyor:

def InitMyVariable():
  if InitMyVariable.my_variable is None:
    InitMyVariable.my_variable = ...
InitMyVariable.my_variable = None

9

catchexceptPython'da çağrılır . bunun dışında böyle basit durumlar için iyi. Orada AttributeErrorbir nesne bir öznitelik olup olmadığını kontrol etmek için kullanılabilir olduğunu.


5

Bu tür durumları işlemek için genellikle iyi çalışan bir yol, değişkenin var olup olmadığını açıkça kontrol etmemek, ancak devam edin ve muhtemelen mevcut olmayan değişkenin ilk kullanımını bir denemede / NameError'da sarmaktır:

# Search for entry.
for x in y:
  if x == 3:
    found = x

# Work with found entry.
try:
  print('Found: {0}'.format(found))
except NameError:
  print('Not found')
else:
  # Handle rest of Found case here
  ...

3

Özel bir işlev oluşturdum.

def exists(var):
     var_exists = var in locals() or var in globals()
     return var_exists

Ardından, variable_namekontrol etmek istediğiniz değişkenle değiştirilen aşağıdaki işlevi çağırın :

exists("variable_name")

Dönecek TrueveyaFalse


2
Hayır, bu işe yaramaz. locals()... err ... fonksiyonuna yerel exists😅
bgusach

1
1) locals () işlevi yereldir. 2) Neden var_exists'in ekstra ataması?
Dave
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.