Apakah mungkin untuk meneruskan-mendeklarasikan fungsi dengan Python? Saya ingin mengurutkan daftar menggunakan cmp
fungsi saya sendiri sebelum dideklarasikan.
print "\n".join([str(bla) for bla in sorted(mylist, cmp = cmp_configs)])
Saya telah mengatur kode saya untuk memasukkan definisi cmp_configs
metode setelah doa. Gagal dengan kesalahan ini:
NameError: name 'cmp_configs' is not defined
Apakah ada cara untuk "mendeklarasikan" cmp_configs
metode sebelum digunakan? Itu akan membuat kode saya terlihat lebih bersih?
Saya berasumsi bahwa beberapa orang akan tergoda untuk memberi tahu saya bahwa saya harus mengatur ulang kode saya sehingga saya tidak memiliki masalah ini. Namun, ada beberapa kasus di mana hal ini mungkin tidak dapat dihindari, misalnya ketika menerapkan beberapa bentuk rekursi. Jika Anda tidak menyukai contoh ini, asumsikan bahwa saya memiliki kasus di mana itu benar - benar perlu untuk maju menyatakan suatu fungsi.
Pertimbangkan kasus ini di mana penerusan maju sebuah fungsi akan diperlukan dalam Python:
def spam():
if end_condition():
return end_result()
else:
return eggs()
def eggs():
if end_condition():
return end_result()
else:
return spam()
Di mana end_condition
dan end_result
telah ditentukan sebelumnya.
Apakah satu-satunya solusi untuk mengatur ulang kode dan selalu meletakkan definisi sebelum pemanggilan?
sumber
main()
?import your_module
Apa yang dapat Anda lakukan adalah membungkus doa menjadi fungsi tersendiri.
Yang seperti itu
akan pecah, tapi
akan bekerja dengan baik.
Aturan umum dalam
Python
adalah tidak bahwa fungsi harus didefinisikan lebih tinggi dalam kode (seperti dalamPascal
), tetapi itu harus didefinisikan sebelum penggunaannya.Semoga itu bisa membantu.
sumber
if __name__=="__main__":
solusinya bekerja.Jika Anda memulai skrip Anda melalui yang berikut ini:
maka Anda mungkin tidak perlu khawatir tentang hal-hal seperti "pernyataan maju". Anda lihat, penerjemah akan memuat semua fungsi Anda dan kemudian mulai fungsi utama Anda (). Tentu saja, pastikan Anda memiliki semua impor yang benar juga ;-)
Kalau dipikir-pikir, saya belum pernah mendengar hal seperti "forward declaration" dengan python ... tapi sekali lagi, saya mungkin salah ;-)
sumber
Jika panggilan ke cmp_configs ada di dalam definisi fungsinya sendiri, Anda seharusnya baik-baik saja. Saya akan memberi contoh.
Secara umum, menempatkan kode Anda di dalam fungsi (seperti main ()) akan menyelesaikan masalah Anda; panggil saja main () di akhir file.
sumber
Saya minta maaf karena menghidupkan kembali utas ini, tetapi ada strategi yang tidak dibahas di sini yang mungkin berlaku.
Menggunakan refleksi dimungkinkan untuk melakukan sesuatu yang mirip dengan meneruskan deklarasi. Misalnya katakanlah Anda memiliki bagian kode yang terlihat seperti ini:
Jadi dengan cara ini kita telah menentukan fungsi apa yang ingin kita panggil sebelum benar-benar didefinisikan, secara efektif deklarasi maju. Dalam python pernyataannya
globals()[function_name]()
sama sepertifoo()
jikafunction_name = 'foo'
untuk alasan yang dibahas di atas, karena python harus mencari setiap fungsi sebelum memanggilnya. Jika seseorang menggunakantimeit
modul untuk melihat bagaimana kedua pernyataan ini dibandingkan, mereka memiliki biaya komputasi yang sama persis.Tentu saja contoh di sini sangat tidak berguna, tetapi jika seseorang memiliki struktur kompleks yang diperlukan untuk menjalankan suatu fungsi, tetapi harus dideklarasikan sebelumnya (atau secara struktural tidak masuk akal untuk memilikinya setelah itu), seseorang hanya dapat menyimpan string dan coba panggil fungsi tersebut nanti.
sumber
Tidak ada yang namanya python seperti forward declaration. Anda hanya perlu memastikan bahwa fungsi Anda dideklarasikan sebelum dibutuhkan. Perhatikan bahwa tubuh suatu fungsi tidak ditafsirkan sampai fungsi dijalankan.
Perhatikan contoh berikut:
Anda dapat berpikir bahwa tubuh suatu fungsi hanyalah skrip lain yang akan ditafsirkan begitu Anda memanggil fungsi tersebut.
sumber
Tidak, saya tidak percaya ada cara untuk meneruskan-mendeklarasikan fungsi dengan Python.
Bayangkan Anda adalah juru bahasa Python. Ketika Anda sampai ke garis
Anda tahu apa itu cmp_configs atau tidak. Untuk melanjutkan, Anda harus tahu cmp_configs. Tidak masalah jika ada rekursi.
sumber
Terkadang suatu algoritma paling mudah untuk dipahami dari atas ke bawah, dimulai dengan struktur keseluruhan dan menelusuri detailnya.
Anda dapat melakukannya tanpa meneruskan deklarasi:
sumber
Keluaran:
sumber
Anda tidak bisa meneruskan-mendeklarasikan fungsi dengan Python. Jika Anda memiliki eksekusi logika sebelum Anda mendefinisikan fungsi, Anda mungkin punya masalah. Letakkan tindakan Anda di
if __name__ == '__main__'
akhir skrip Anda (dengan menjalankan fungsi yang Anda beri nama "utama" jika tidak sepele) dan kode Anda akan lebih modular dan Anda akan dapat menggunakannya sebagai modul jika Anda membutuhkannya. untuk.Juga, ganti pemahaman daftar itu dengan generator express (yaitu,
print "\n".join(str(bla) for bla in sorted(mylist, cmp=cmp_configs))
)Juga, jangan gunakan
cmp
, yang sudah usang. Gunakankey
dan sediakan fungsi yang kurang dari itu.sumber
Impor file itu sendiri. Dengan asumsi file tersebut disebut test.py:
sumber
"Atur ulang kode saya sehingga saya tidak memiliki masalah ini." Benar. Mudah untuk dilakukan. Selalu berhasil.
Anda selalu dapat menyediakan fungsi sebelum referensi itu.
"Namun, ada beberapa kasus di mana hal ini mungkin tidak dapat dihindari, misalnya ketika menerapkan beberapa bentuk rekursi"
Tidak dapat melihat bagaimana hal itu mungkin terjadi. Harap berikan contoh tempat di mana Anda tidak dapat menentukan fungsi sebelum digunakan.
sumber
Tunggu sebentar. Ketika modul Anda mencapai pernyataan cetak dalam contoh Anda, sebelum
cmp_configs
telah ditentukan, apa sebenarnya yang Anda harapkan untuk dilakukan?Jika posting Anda dari pertanyaan menggunakan cetak benar-benar mencoba untuk mewakili sesuatu seperti ini:
maka tidak ada persyaratan untuk didefinisikan
cmp_configs
sebelum menjalankan pernyataan ini, cukup tentukan nanti dalam kode dan semua akan baik-baik saja.Sekarang jika Anda mencoba untuk referensi
cmp_configs
sebagai nilai default dari argumen ke lambda, maka ini adalah cerita yang berbeda:Sekarang Anda membutuhkan
cmp_configs
variabel yang ditentukan sebelum Anda mencapai baris ini.[EDIT - bagian selanjutnya ini ternyata tidak benar, karena nilai argumen default akan ditetapkan ketika fungsi dikompilasi, dan nilai itu akan digunakan bahkan jika Anda mengubah nilai cmp_configs nanti.]
Untungnya, Python menjadi tipe-akomodatif apa adanya, tidak peduli apa yang Anda definisikan
cmp_configs
, sehingga Anda bisa saja mengawali dengan pernyataan ini:Dan kompiler akan senang. Pastikan untuk mendeklarasikan yang asli
cmp_configs
sebelum Anda memohonfn
.sumber
Salah satu caranya adalah dengan membuat fungsi handler. Tentukan pawang sejak dini, dan letakkan pawang di bawah semua metode yang perlu Anda panggil.
Kemudian ketika Anda memanggil metode handler untuk memanggil fungsi Anda, mereka akan selalu tersedia.
Pawang bisa mengambil argumen
nameOfMethodToCall
. Kemudian gunakan banyak pernyataan if untuk memanggil metode yang tepat.Ini akan menyelesaikan masalah Anda.
sumber
Ya, kami dapat memeriksa ini.
Memasukkan
Keluaran
Seperti BJ Homer sebutkan di atas komentar di atas, Aturan umum dalam Python bukanlah fungsi yang harus didefinisikan lebih tinggi dalam kode (seperti dalam Pascal), tetapi harus didefinisikan sebelum penggunaannya.
Semoga itu bisa membantu.
sumber
print_lyrics()
dipanggil (digunakan) pada baris 1 sebelum didefinisikan? Saya menyalin kode ini dan mencoba menjalankannya, dan itu memberi saya kesalahanNameError: name 'print_lyrics' is not defined
pada Baris 1. Bisakah Anda menjelaskan ini?