Peraturan skop dalam fungsi Python


Python ialah bahasa berskop statik, walaupun ia sendiri adalah bahasa dinamik. Dalam erti kata lain, skop pembolehubah dalam Python ditentukan oleh kedudukannya dalam kod sumber, yang agak serupa dengan C, tetapi perbezaan skop antara Python dan C masih sangat jelas.


Seterusnya, kita akan bercakap tentang peraturan skop Python, dan kami juga akan menerangkan perbezaan antara Python dan C dari segi skop.

Dalam Python 2.0 dan versi sebelumnya, Python hanya menyokong 3 jenis skop, iaitu skop tempatan, skop global, dan skop terbina dalam dalam Python 2.2, Python secara rasminya memperkenalkan skop baharu--- Skop bersarang; skop bersarang boleh dihidupkan sebagai pilihan; pengenalan skop bersarang pada asasnya melaksanakan sokongan untuk penutupan dalam Python Terdapat banyak penjelasan di Internet tentang pengetahuan penutupan , yang tidak akan dibincangkan secara terperinci di sini. Sejajar dengan itu, susunan carian berubah-ubah berubah daripada LGB sebelumnya kepada LEGB (L: Local, E: Enclosing, G: Global, B: Built-in).


Dalam Python, tidak ada blok kod yang boleh memperkenalkan skop baharu, yang sangat berbeza daripada C:


#include<stdio.h>int main() {    if(2 > 0) {        int i = 0;
    }
    printf("i = %d", i);    return 0;
}

Dalam kod ini, sub skop jika ayat tersebut memperkenalkan. Pembolehubah i wujud dalam skop tempatan ini tetapi tidak dapat dilihat oleh dunia luar Oleh itu, rujukan seterusnya kepada pembolehubah i dalam fungsi printf akan menyebabkan ralat kompilasi.

Walau bagaimanapun, ini tidak berlaku dalam Python:

if True:
    i = 0print i

Dalam kod ini, klausa if tidak memperkenalkan skop tempatan, pembolehubah i masih dalam skop global, oleh itu, pembolehubah i adalah untuk seterusnya Kenyataan cetakan kelihatan.

Malah, dalam Python, hanya modul, kelas dan fungsi akan memperkenalkan skop baharu, dan blok kod lain tidak akan memperkenalkan skop baharu.

Dalam Python, anda tidak perlu mengisytiharkan pembolehubah sebelum menggunakannya, tetapi sebelum anda benar-benar menggunakannya, ia mestilah terikat pada pengikatan nama objek akan memperkenalkan pembolehubah baharu dalam skop semasa sambil melindungi dunia luar. Pembolehubah dengan nama yang sama dalam skop lapisan, tidak kira di mana dalam skop semasa pengikatan nama berlaku.

def f():    print i
f()


Hasil larian akan menunjukkan: NameError: nama global 'i' tidak ditakrifkan. Python mula-mula mencari pembolehubah i dalam skop tempatan fungsi f, dan carian gagal Kemudian ia mencari pembolehubah i dalam skop global dan skop terbina dalam, tetapi masih gagal, dan akhirnya membuang pengecualian NameError.

i = 0def f():
    i = 8    print i
f()print i


Keputusan larian menunjukkan: 8 dan 0. i = 8 ialah operasi mengikat nama Ia memperkenalkan pembolehubah baru i dalam skop tempatan fungsi f dan menyekat pembolehubah global i. Oleh itu, pernyataan cetakan di dalam f melihat pembolehubah tempatan i, dan pernyataan cetakan di luar f melihat pembolehubah tempatan i. Apa yang dilihat oleh pernyataan ialah pembolehubah global i.

i = 0def f():    print i
    i = 0
f()


Hasil larian menunjukkan: UnboundLocalError: pembolehubah tempatan 'i' dirujuk sebelum tugasan. Dalam contoh ini, pembolehubah i dalam fungsi f ialah pembolehubah tempatan, tetapi apabila pernyataan cetakan menggunakannya, ia tidak terikat pada sebarang objek, jadi pengecualian dilemparkan.

print i
i = 0


Sama ada ia dijalankan secara interaktif atau sebagai fail skrip, hasilnya menunjukkan: NameError: nama 'i' tidak ditakrifkan. Output di sini berbeza daripada contoh sebelumnya kerana ia berada dalam skop peringkat atas (skop modul). Untuk kod modul, kod tidak menjalani sebarang prapemprosesan sebelum pelaksanaan, tetapi untuk badan fungsi, kod telah pun menjalani prapemprosesan sebelum dijalankan, jadi tidak kira di mana pengikatan nama berlaku dalam skop, ia akan Dapat merasakannya. Walaupun Python ialah bahasa berskop statik, carian nama berlaku secara dinamik, jadi masalah nama tidak ditemui sehingga masa jalan.


Dalam Python, pengikatan nama memperkenalkan pembolehubah baharu dalam skop yang dimilikinya dan mengikatnya pada objek. Pengikatan nama berlaku dalam situasi berikut:


  1. Pengisytiharan parameter: Pengisytiharan parameter memperkenalkan pembolehubah baharu dalam skop setempat fungsi; pembolehubah akan memperkenalkan pembolehubah baharu dalam skop semasa, dan operasi tugasan seterusnya akan mengikat semula pembolehubah
  2. Definisi kelas dan fungsi: Definisi kelas dan fungsi memperkenalkan nama kelas dan nama fungsi sebagai pembolehubah Skop, kelas semasa badan dan badan fungsi akan membentuk satu lagi skop; pembolehubah (pembolehubah gelung) dalam skop semasa;
  3. kecuali pernyataan: kecuali pernyataan memperkenalkan pembolehubah baharu (objek pengecualian) dalam skop semasa.
  4. Dalam Python, skop yang diperkenalkan oleh definisi kelas tidak kelihatan kepada fungsi ahli Ini sangat berbeza daripada C++ atau Java, jadi dalam Python, fungsi ahli ingin merujuk kepada pembolehubah definisi badan kelas A mesti dirujuk melalui nama diri atau kelas.
  5. Penambahan skop bersarang akan menyebabkan beberapa kod gagal untuk menyusun atau mendapat hasil larian yang berbeza Di sini jurubahasa Python akan membantu anda mengenal pasti tempat ini yang mungkin menyebabkan masalah dan memberi amaran.
  6. Fungsi setempat mengembalikan semua pembolehubah tempatan, tetapi tidak akan mengembalikan pembolehubah dalam skop bersarang.