Apakah mungkin hanya untuk mendeklarasikan variabel tanpa memberikan nilai apa pun dalam Python?

288

Apakah mungkin untuk mendeklarasikan variabel dengan Python, seperti itu ?:

var

sehingga diinisialisasi ke Tidak ada? Sepertinya Python mengizinkan ini, tapi begitu Anda mengaksesnya, crash. Apakah ini mungkin? Jika tidak, mengapa?

EDIT: Saya ingin melakukan ini untuk kasus-kasus seperti ini:

value

for index in sequence:

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

Duplikat

Terkait

Joan Venge
sumber
1
dapat memposting program kecil yang menyebabkan ini.
Preet Sangha
Anda telah memposting pertanyaan duplikat, memberikan suara untuk menutup pertanyaan ini untuk yang lainnya.
Jerub
Masih ada beberapa perbedaan, yang satu ini berkaitan dengan tidak dapat menggunakan variabel hanya dengan mendeklarasikan.
Joan Venge
Sebenarnya tidak ada yang namanya mendeklarasikan variabel di dunia python, seperti yang dijelaskan pertanyaan pertama Anda.
Harley Holcombe
1
mengapa tidak ada yang pernah mengatakan 'hanya menetapkan untuk itu' karena variabel tidak ada sebelum mereka ditugaskan ke titik. Dan variabel dalam python tidak mengandung informasi tipe. Objek melakukan itu. Variabel hanya untuk memegang objek pada saat itu. Selanjutnya, program di atas harus membuang pengecualian NameError di baris pertama. (Itulah yang saya dapatkan di 2.X dan 3.X keduanya)
osirisgothra

Jawaban:

359

Mengapa tidak lakukan saja ini:

var = None

Python dinamis, jadi Anda tidak perlu mendeklarasikan sesuatu; mereka ada secara otomatis di ruang lingkup pertama tempat mereka ditugaskan. Jadi, yang Anda butuhkan hanyalah pernyataan tugas lama seperti biasa di atas.

Ini bagus, karena Anda tidak akan pernah berakhir dengan variabel yang tidak diinisialisasi. Tapi hati-hati - ini tidak berarti bahwa Anda tidak akan berakhir dengan variabel yang diinisialisasi salah . Jika Anda Nonemenginginkan sesuatu , pastikan itu yang Anda inginkan, dan tetapkan sesuatu yang lebih bermakna jika Anda bisa.

Todd Gamblin
sumber
1
Saya akan melakukan itu, tetapi hanya berpikir secara implisit itu akan melakukan itu.
Joan Venge
7
Intinya adalah agar ini menjadi eksplisit, bukan implisit. Tidak menebak-nebak apa nilai awalnya. Tidak heran jika variabel yang tidak diinisialisasi melempar pengecualian atau secara ajaib memiliki nilai berguna.
S.Lott
2
Satu-satunya masalah yang saya miliki dengan ini adalah saya melacak counter (minValue) dan setiap kali nilai lebih rendah dari itu, saya menetapkannya untuk menjadi minValue baru. Jika saya menyatakan minValue sebagai Tidak Ada pada awalnya, maka ternyata itu masih lebih rendah daripada angka yang saya bandingkan. Saya akhirnya hanya menginisialisasi di sys.maxint
TJ Biddle
... mereka ada secara otomatis di ruang lingkup pertama tempat mereka ditugaskan. Jadi, Anda harus memburu tugas pertama itu dan mencari tahu. huh!
Ed Randall
56

Saya sungguh-sungguh merekomendasikan bahwa Anda membaca bahasa lain memiliki "variabel" (saya menambahkannya sebagai tautan terkait) - dalam dua menit Anda akan tahu bahwa Python memiliki "nama", bukan "variabel".

val = None
# ...
if val is None:
   val = any_object
jfs
sumber
Anda juga bisa menulis val = val or any_objectuntuk menginisialisasi itu.
Zoltán
1
@ Zoltán: rusak jika nilai yang valid untuk val adalah "false" misalnya, nol atau kosong. Gunakan isuntuk menguji apakah suatu nilai None.
jfs
Setelah membaca artikel di tautan yang disediakan, tampaknya lebih dari sekadar menyesatkan semantik.
Andrew P.
29

Di Python 3.6+ Anda bisa menggunakan Anotasi Variabel untuk ini:

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

PEP 484 memperkenalkan tip tipe, alias tipe anotasi. Meskipun fokus utamanya adalah anotasi fungsi, ia juga memperkenalkan gagasan komentar tipe ke variabel anotasi:

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

PEP 526 bertujuan untuk menambahkan sintaks ke Python untuk menganotasi jenis variabel (termasuk variabel kelas dan variabel instan), alih-alih mengungkapkannya melalui komentar:

captain: str  # Note: no initial value!

Tampaknya lebih langsung sejalan dengan apa yang Anda tanyakan "Apakah mungkin hanya untuk mendeklarasikan variabel tanpa menetapkan nilai apa pun dalam Python?"

Tagar
sumber
2
Jawaban luar biasa
Ben
16

Saya tidak yakin apa yang Anda coba lakukan. Python adalah bahasa yang sangat dinamis; Anda biasanya tidak perlu mendeklarasikan variabel sampai Anda benar-benar akan menetapkan atau menggunakannya. Saya pikir apa yang ingin Anda lakukan adalah adil

foo = None

yang akan menetapkan nilai Noneke variabel foo.

EDIT: Apa yang benar-benar ingin Anda lakukan hanyalah ini:

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

Agak sulit untuk mengatakan apakah itu benar-benar gaya yang tepat untuk digunakan dari contoh kode pendek seperti itu, tetapi ini adalah cara yang lebih "Pythonic" untuk bekerja.

EDIT: di bawah ini adalah komentar oleh JFS (diposting di sini untuk menunjukkan kode)

Tidak terkait dengan pertanyaan OP tetapi kode di atas dapat ditulis ulang sebagai:

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)

CATATAN: jika some_condition()memunculkan pengecualian maka foundtidak terikat.
CATATAN: jika len (urutan) == 0 maka itemtidak terikat.

Kode di atas tidak disarankan. Tujuannya adalah untuk menggambarkan cara kerja variabel lokal, yaitu apakah "variabel" "didefinisikan" hanya dapat ditentukan saat runtime dalam kasus ini. Cara yang lebih disukai:

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

Atau

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

if found:
   do_something(item)
kquinn
sumber
Apakah ada perbedaan antara bahasa dinamis dan bahasa yang sangat dinamis?
Gavin Miller
Ada artikel bagus yang menjelaskan berbagai sumbu pengetikan bahasa pemrograman, dan bagaimana mereka kontinum, bukan nilai boolean; sayangnya saya tidak pernah dapat menemukan artikel yang lagi ketika saya ingin mengutip itu :( Saya menganggap Python "sangat dinamis" karena di ujung beberapa sumbu.
kquinn
3

Saya biasanya menginisialisasi variabel menjadi sesuatu yang menunjukkan tipe suka

var = ""

atau

var = 0

Jika akan menjadi objek maka jangan menginisialisasi sampai Anda instantiate:

var = Var()
Andrew Hare
sumber
3

Nah, jika Anda ingin memeriksa apakah suatu variabel didefinisikan atau tidak, mengapa tidak memeriksa apakah ada dalam array lokal () atau global ()? Kode Anda ditulis ulang:

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

Jika itu variabel lokal yang Anda cari, maka gantilah global () dengan lokal ().

Johan
sumber
2

Pertama-tama, tanggapan saya terhadap pertanyaan yang awalnya Anda ajukan

T: Bagaimana saya menemukan jika suatu variabel didefinisikan pada suatu titik dalam kode saya?

A: Baca di file sumber sampai Anda melihat baris di mana variabel itu didefinisikan.

Namun lebih lanjut, Anda telah memberikan contoh kode bahwa ada berbagai permutasi yang cukup pythonic. Anda mencari cara untuk memindai urutan elemen yang cocok dengan suatu kondisi, jadi inilah beberapa solusi:

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

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

Jelas dalam contoh ini Anda dapat mengganti raisedengan return Nonetergantung pada apa yang ingin Anda capai.

Jika Anda menginginkan semua yang cocok dengan kondisi Anda bisa melakukan ini:

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

    return matches

Ada cara lain untuk melakukan ini dengan yieldyang saya tidak akan repot menunjukkan kepada Anda, karena itu cukup rumit dalam cara kerjanya.

Lebih lanjut, ada satu cara untuk mencapai hal ini:

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

Jika saya memahami contoh Anda dengan benar, Anda tidak perlu merujuk ke 'nilai' dalam pernyataan if. Anda keluar dari loop segera setelah itu dapat diatur untuk apa saja.

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

Anda sepertinya sedang mencoba menulis C dengan Python. Jika Anda ingin menemukan sesuatu secara berurutan, Python memiliki fungsi builtin untuk melakukan itu, seperti

value = sequence.index(blarg)

sumber
1

Ini adalah pertanyaan yang bagus dan sayangnya jawaban buruk seperti var = Nonesudah memberikan nilai, dan jika skrip Anda berjalan beberapa kali ditimpa dengan Nonesetiap waktu.

Ini tidak sama dengan mendefinisikan tanpa penugasan. Saya masih mencoba mencari cara untuk mem-bypass masalah ini.

zinturis
sumber
1

Apakah mungkin untuk mendeklarasikan variabel dengan Python (var = Tidak Ada):

def decl_var(var=None):
if var is None:
    var = []
var.append(1)
return var
Abderrahim
sumber
0
var_str = str()
var_int = int()
Zaur
sumber
pria nakal nakal nakal! variabel tidak mengaitkan tipe, objek lakukan. var_str tidak boleh dibatasi dengan nama generik seperti itu. Jika Anda akan melakukan ini, buatlah itu bermakna seperti 'var_age' atau 'var_name' misalnya. Nilai-nilai tersebut dapat diambil sebagai bilangan bulat atau string atau apa pun yang Anda inginkan, dan diubah menjadi objek, semangat apa yang membuat python berbeda dari bahasa lain. Mereka mengatakan jika Anda merasa perlu melakukan ini sepanjang waktu, Anda mungkin ingin menggunakan bahasa lain.
osirisgothra
0

Jika Nonemerupakan nilai data yang valid maka Anda perlu variabel dengan cara lain. Anda bisa menggunakan:

var = object()

Sentinel ini disarankan oleh Nick Coghlan .

Chris_Rands
sumber
0

Anda dapat menipu penerjemah dengan oneliner jelek ini. if None: var = None Ia tidak melakukan apa-apa selain menambahkan variabel varke kamus variabel lokal, bukan menginisialisasi. Interpreter akan melempar pengecualian UnboundLocalError jika Anda mencoba menggunakan variabel ini dalam suatu fungsi sesudahnya. Ini akan bekerja untuk versi python yang sangat kuno juga. Tidak sederhana, tidak cantik, tetapi jangan berharap banyak dari python.

ZAB
sumber