Deklarasikan fungsi di akhir file dengan Python

94

Apakah mungkin untuk memanggil suatu fungsi tanpa terlebih dahulu mendefinisikannya sepenuhnya? Ketika mencoba ini saya mendapatkan kesalahan: " function_name tidak ditentukan". Saya berasal dari latar belakang C ++ jadi masalah ini membuat saya bingung.

Mendeklarasikan fungsi sebelum bekerja:

def Kerma():
        return "energy / mass"    

print Kerma()

Namun, mencoba memanggil fungsi tanpa mendefinisikannya terlebih dahulu memberikan masalah:

print Kerma()

def Kerma():
    return "energy / mass"

Di C ++, Anda bisa mendeklarasikan fungsi setelah panggilan setelah Anda menempatkan headernya sebelumnya.

Apakah saya melewatkan sesuatu di sini?

TheGentleOne
sumber
5
Di Python tidak ada "deklarasikan". Ada definisi (yang harus lengkap) atau tidak ada.
S. Lott
2
Anda berkata, "itu memberi masalah". Dapatkah Anda menguraikan itu?
Martin Del Vecchio
Kemungkinan duplikat fungsi Deklarasi dalam python setelah panggilan
pengguna
Jika ada yang bertanya-tanya:Kerma is an acronym for "kinetic energy released per unit mass"
segera
1
Saya tahu ini super tua, tetapi mengapa tidak ada yang merekomendasikan meletakkan fungsi dalam .pyfile terpisah dan mengimpornya? Apakah ada konsekuensi yang tidak diinginkan?
Kyle

Jawaban:

145

Salah satu cara yang agak idiomatis dalam Python adalah menulis:

def main():
    print Kerma()

def Kerma():
    return "energy / mass"    

if __name__ == '__main__':
    main()

Ini memungkinkan Anda untuk menulis kode Anda dalam urutan yang Anda suka selama Anda tetap memanggil fungsi tersebut maindi akhir.

Muhammad Alkarouri
sumber
4
@Muhammad: meskipun ini adalah pendekatan yang layak, itu pasti tidak idiomatis dalam Python. Sebaliknya, Anda akan melihat sebagian besar mainfungsi biasanya ditempatkan di bagian akhir.
Eli Bendersky
15
@ Eli Bendersky: Saya akan menyampaikan bahwa if __name__ == '__main__':sakelar adalah bagian idiomatik yang umum.
S. Lott
2
@Eli: bagian idiomatik adalah klausa if di bagian akhir: tidak ada kode di tingkat atas modul, kemudian di bagian akhir memanggil fungsi utama jika modul tersebut adalah main .
Ned Batchelder
1
@Eli: Bagian idiomatik adalah if ... __main__':. Saya tidak mengatakan bahwa mainharus ditempatkan di atas sisa kode. Saya katakan bagian penting adalah memanggil _\_main__di akhir, dan tidak masalah di mana Anda menempatkan definisinya.
Muhammad Alkarouri
2
Dengan if name == ' main ': switch itu menjadi tidak relevan bagaimana Anda mengurutkan fungsi Anda. Itu hal yang benar (TM) untuk dilakukan.
MKesper
18

Ketika modul Python (file .py) dijalankan, pernyataan tingkat atas di dalamnya dijalankan sesuai urutan kemunculannya, dari atas ke bawah (awal hingga akhir). Ini berarti Anda tidak dapat mereferensikan sesuatu sampai Anda mendefinisikannya. Misalnya, berikut ini akan menghasilkan kesalahan yang ditampilkan:

c = a + b  # -> NameError: name 'a' is not defined
a = 13
b = 17

Tidak seperti banyak bahasa lain, defdan classpernyataan dapat dieksekusi dengan Python — bukan hanya deklaratif — jadi Anda tidak dapat mereferensikan salah satunya aatau bsampai itu terjadi dan ditetapkan. Inilah mengapa contoh pertama Anda mengalami masalah — Anda mereferensikan Kerma()fungsi sebelum defpernyataannya dieksekusi dan badan telah diproses dan objek fungsi yang dihasilkan terikat ke nama fungsi, jadi tidak ditentukan pada saat itu dalam skrip.

Program dalam bahasa seperti C ++ biasanya diproses terlebih dahulu sebelum dijalankan dan selama tahap kompilasi ini, seluruh program dan #includefile apa pun yang dirujuknya dibaca dan diproses sekaligus. Tidak seperti Python, bahasa ini menampilkan pernyataan deklaratif yang memungkinkan nama dan urutan pemanggilan fungsi (atau tipe variabel statis) untuk dideklarasikan (tetapi tidak ditentukan), sebelum digunakan sehingga ketika kompilator menemukan namanya, ia memiliki informasi yang cukup untuk memeriksa penggunaan, yang terutama memerlukan pemeriksaan jenis dan konversi jenis, tidak ada yang mengharuskan konten atau badan kode aktualnya telah ditentukan.

martineau.dll
sumber
Bukannya bahasa dinamis tidak bisa melakukan itu. Perl adalah bahasa dinamis dan Anda dapat memanggil suatu fungsi sebelum Anda mendefinisikannya. Itu karena ia memiliki fase kompilasi dan fase eksekusi (meskipun anehnya, tetapi berguna, Anda dapat mengatur untuk mengeksekusi kode selama fase kompilasi). Ini bekerja: doit(); sub doit { print("I'm doing it!\n"); }
John Deighan
9

Ini tidak mungkin dilakukan di Python, tetapi terus terang Anda akan segera menyadari bahwa Anda tidak membutuhkannya sama sekali. Cara Pythonic untuk menulis kode adalah dengan membagi program Anda menjadi modul yang mendefinisikan kelas dan fungsi, dan satu "modul utama" yang mengimpor semua yang lain dan berjalan.

Untuk skrip membuang-pergi sederhana biasakan menempatkan "bagian yang dapat dieksekusi" di akhir, atau lebih baik lagi, belajar menggunakan shell Python interaktif.

Eli Bendersky
sumber
1

Python adalah bahasa dinamis dan penerjemah selalu mengambil status variabel (fungsi, ...) seperti pada saat memanggilnya. Anda bahkan dapat mendefinisikan ulang fungsi di beberapa blok if dan memanggilnya setiap kali secara berbeda. Itulah mengapa Anda harus mendefinisikan mereka sebelum memanggil mereka.

eumiro
sumber
1

Jika Anda ingin menjadi seperti C ++ dan menggunakan semua yang ada di dalam fungsi. Anda dapat memanggil fungsi pertama dari bagian bawah file, seperti ini:

def main():
    print("I'm in main")
    #calling a although it is in the bottom
    a()

def b():
   print("I'm in b")

def a():
   print("I'm in a")
   b()

main()

Dengan cara itu python pertama 'membaca' seluruh file dan baru kemudian memulai eksekusi

arye
sumber