Bagaimana saya memeriksa apakah ada variabel?


954

Saya ingin memeriksa apakah ada variabel. Sekarang saya melakukan sesuatu seperti ini:

try:
   myVar
except NameError:
   # Do something.

Apakah ada cara lain tanpa pengecualian?


15
Apa yang salah dengan pengecualian ini?
S.Lott

10
@ S.Lott: jika myVarada sesuatu yang benar-benar rumit, yang membutuhkan waktu lama untuk menghasilkan / mengevaluasi, bukankah tryhal itu akan melambat?
dbliss

3
@ Dbliss: Ini variabel. Selain dari beberapa kasus yang sangat aneh jika Anda melakukan sesuatu yang gila dengan execatau metaclasses, itu tidak akan mahal.
user2357112 mendukung Monica

Jawaban yang lebih lengkap: stackoverflow.com/a/1592578/1661797
nickboldt

Jawaban:


1628

Untuk memeriksa keberadaan variabel lokal:

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

Untuk memeriksa keberadaan variabel global:

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

Untuk memeriksa apakah suatu objek memiliki atribut:

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

29
Oke, dan bagaimana saya bisa memeriksa atribut yang ada di kelas?
Max Frai

7
dan bagaimana Anda mengubah nama variabel yang mungkin tidak ada menjadi string?
SilentGhost

15
Tapi OP mengetik kode, mereka bisa mengetik 'myVar' di myVar. Jika nama variabel tidak diketahui saat kode ditulis, itu akan disimpan dalam variabel string saat runtime, dan cek yang saya posting juga akan berfungsi.
Ayman Hourieh

8
Ada juga variabel bawaan, dan, jika Anda memiliki fungsi bersarang, variabel dalam cakupan luar. Jika Anda ingin memeriksa semuanya, Anda mungkin lebih baik memicu NameErrorsemua.
Petr Viktorin

14
Saya suka yang terbaik if hasattr(obj, 'attr_name'):yang bekerja untuk kelas juga: yaituif hasattr(self, 'attr_name'):
Ron Kalian

118

The Penggunaan variabel yang belum didefinisikan atau set (secara implisit maupun eksplisit) hampir selalu hal yang buruk dalam setiap bahasa, karena sering menunjukkan bahwa logika program belum memikirkan dengan baik, dan kemungkinan hasil dalam perilaku yang tidak terduga.

Jika Anda perlu melakukannya di Python, trik berikut, yang serupa dengan Anda, akan memastikan bahwa variabel memiliki beberapa nilai sebelum digunakan:

try:
    myVar
except NameError:
    myVar = None

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

Namun, saya masih tidak yakin itu ide yang bagus - menurut saya, Anda harus mencoba untuk memperbaiki kode Anda sehingga situasi ini tidak terjadi.


8
Mungkin itu adalah variabel ketergantungan, dan menurut versi / platform itu mungkin ada atau tidak ada, dan tidak ada cara lain untuk mengetahui versi apa itu.
WhyNotHugo

35
Variabel status tidak ada sebelum ditugaskan - jika Anda menggambar garis dari posisi sebelumnya ke posisi saat ini, lalu atur sebelumnya = saat ini, itu tidak berarti Anda "tidak tahu variabel Anda" pada panggilan pertama. Dan menulis baris kode tambahan untuk menginisialisasi sebelumnya = nol di luar rutin imbang tidak berarti Anda "tahu variabel Anda" lebih baik.
Dave

4
Maksud saya adalah bahwa blok "if last: draw (last, current); last = current" mudah dimengerti dan bukan pemrograman yang buruk. Menambahkan "coba / kecuali" untuk memeriksa keberadaan "terakhir" sebelum dapat mengujinya akan mengurangi keterbacaan kode itu.
Dave

23
"Penggunaan variabel yang belum didefinisikan sebenarnya merupakan hal yang buruk dalam bahasa apa pun" Jangan gunakan pidato merendahkan saya. Beberapa dari kita menggunakan Python untuk skrip matematika atau statistik sederhana menggunakan IDE seperti Spyder yang berfungsi seperti Matlab. Masuk akal kadang-kadang di lingkungan tersebut untuk memungkinkan pengguna untuk mendefinisikan variabel di konsol global dan memeriksa sebaliknya jika mereka tidak dideklarasikan dalam skrip seperti ketika melakukan matematika di Matlab.
Ricardo Cruz

15
@ Ricardo, mungkin, daripada menganggapnya merendahkan, Anda mungkin ingin setidaknya mempertimbangkan kemungkinan bahwa itu hanya nasihat yang baik dari seseorang yang mungkin lebih berpengetahuan luas :-) Atau apakah Anda menganggapnya sama-sama merendahkan jika saya menyarankan agar penggunaan global tidak dibatasi? variabel, kode spageti, objek dewa, merilis kode yang belum diuji, atau menulis sistem operasi dalam COBOL? Jawaban saya menyatakan mengapa saya pikir itu ide yang buruk (dan tidak ada dalam pertanyaan yang mengindikasikan mengapa OP berpikir itu perlu) tetapi masih memberikan jalan jika mereka benar-benar ingin melakukannya.
paxdiablo

52

Cara sederhana adalah menginisialisasi pada pepatah pertama myVar = None

Kemudian di kemudian hari:

if myVar is not None:
    # Do something

2
Ada banyak hal yang harus diperbaiki dalam jawaban ini. Sebaliknya - Cara sederhana adalah mendeklarasikannya terlebih dahulu. myVar = none # do stuff... if not myVar: # give myVar a value myVar = 'something'
Shawn Mehan

Saya sangat menyukai yang ini karena saya mengatur semuanya menjadi Tidak ada dalam exceptpernyataan saya
HashRocketSyntax

mengapa tidak sesuatu seperti: if myVar: # Do something Ini menghindari kebutuhan untuk membaca negatif ganda
jisnow

@jjisnow Karena Anda ingin kondisi ini benar meskipun myVardaftar kosong, nol, string kosong dll.
Gabriel

7
@jjisnow if myVar: # Do somethingmelempar NameErrorpython3 jika myVar tidak dideklarasikan
Agile Bean

25

Menggunakan try / kecuali adalah cara terbaik untuk menguji keberadaan variabel. Tetapi hampir pasti ada cara yang lebih baik untuk melakukan apa pun yang Anda lakukan daripada menetapkan / menguji variabel global.

Misalnya, jika Anda ingin menginisialisasi variabel tingkat modul saat pertama kali Anda memanggil beberapa fungsi, Anda lebih baik dengan kode seperti ini:

my_variable = None

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

2
Saya mencoba untuk tidak menggunakan ini, karena mencemari namespace global. Salah satu cara untuk menghindari ini adalah dengan membuat fungsi kelas, dengan my_variable sebagai variabel kelas, dan mendefinisikan panggilan sebagai isi dari fungsi yang ada, tetapi itu menyebalkan untuk kode dan membuka banyak pertanyaan lain. Saya lebih suka menggunakan atribut fungsi, lihat di bawah.
samwyse

17

untuk objek / modul, Anda juga bisa

'var' in dir(obj)

Sebagai contoh,

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

11

Saya akan berasumsi bahwa tes akan digunakan dalam suatu fungsi, mirip dengan jawaban user97370 . Saya tidak suka jawaban itu karena mencemari namespace global. Salah satu cara untuk memperbaikinya adalah dengan menggunakan kelas sebagai gantinya:

class InitMyVariable(object):
  my_variable = None

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

Saya tidak suka ini, karena mempersulit kode dan membuka pertanyaan seperti, haruskah ini mengkonfirmasi ke pola pemrograman Singleton? Untungnya, Python telah mengizinkan fungsi untuk memiliki atribut untuk sementara waktu, yang memberi kami solusi sederhana ini:

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

9

catchdisebut exceptdengan Python. selain itu tidak masalah untuk kasus sederhana seperti itu. Ada AttributeErroryang dapat digunakan untuk memeriksa apakah suatu objek memiliki atribut.


5

Cara yang sering bekerja dengan baik untuk menangani situasi semacam ini adalah dengan tidak secara eksplisit memeriksa apakah variabel itu ada tetapi lanjutkan dan bungkus penggunaan pertama dari variabel yang mungkin tidak ada dalam percobaan / kecuali NameError:

# 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

Saya membuat fungsi khusus.

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

Kemudian panggil fungsi seperti berikut menggantikan variable_namedengan variabel yang ingin Anda periksa:

exists("variable_name")

Akan kembali TrueatauFalse


2
Tidak, ini tidak akan berhasil. locals()is ... err ... lokal ke fungsi exists😅
bgusach

1
1) Fungsi penduduk lokal () adalah lokal. 2) Mengapa tugas tambahan var_exists?
Dave
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.