Bagaimana Anda menulis fungsi di dalam fungsi python?

Fungsi bersarang (atau dalam, bersarang) adalah fungsi yang kita definisikan di dalam fungsi lain untuk secara langsung mengakses variabel dan nama yang ditentukan dalam fungsi terlampir. Fungsi bersarang memiliki banyak kegunaan, terutama untuk membuat penutupan dan dekorator

Dalam panduan ini, kita akan

  • pelajari cara menyediakan enkapsulasi dan menyembunyikan fungsi dari akses eksternal

  • menulis fungsi pembantu untuk membuat kode lebih mudah digunakan kembali

  • mengimplementasikan penutupan untuk mempertahankan status di antara panggilan

  • mari buat dekorator untuk menambahkan perilaku ke fungsi yang ada

Membuat Fungsi Bersarang dengan Python

Mari kita mulai dengan contoh kode yang berisi fungsi bersarang

def outer_func():
    def inner_func():
        print("Hello, World!")
    inner_func()
outer_func()

KELUARAN

Halo Dunia

Dalam kode ini, kami mendefinisikan secara internal untuk menampilkan string. Untuk melakukan ini, kami memanggil baris terakhir. inner_func()  outer_func() Halo, Dunia. fungsi_dalam() fungsi_luar()

Penggunaan utama fungsi internal adalah kemudahannya untuk mengakses variabel dan objek dari fungsi langganan ("eksternal"). Fungsi penutup menyediakan namespace yang tersedia untuk fungsi bersarang

def outer_func(who):
    def inner_func():
        print(f"Hello, {who}")
    inner_func()
outer_func("World!")
_

KELUARAN

Halo Dunia

Sekarang kita bisa mengirimkan string sebagai argumen ke fungsi, dan akan merujuk argumen ini melalui namanya. Nama ini didefinisikan dalam lingkup lokal. Nama yang kami definisikan dalam lingkup lokal dari fungsi luar didefinisikan sebagai. Mereka non-lokal dari sudut pandang. external_func() inner_func() yang outer_func() nonlocal inner_func()

Contoh lain dari fungsi bersarang yang lebih kompleks

def factorial(number):
    if not isinstance(number, int):
        raise TypeError("The number must be whole.")
    if number < 0:
        raise ValueError("The number must be non-negative.")
    #Factorial calculation
    def inner_factorial(number):
        if number <= 1:
            return 1
        return number * inner_factorial(number - 1)
    return inner_factorial(number)
 factorial(4)

KELUARAN

24

Dalam fungsinya, pertama-tama kita memvalidasi input untuk memastikan pengguna memberikan bilangan bulat non-negatif. Kami kemudian mendefinisikan fungsi dalam bernama rekursif yang menghitung faktorial. Pada langkah terakhir, perhitungan yang sesuai dipanggil dan dilakukan. faktorial() faktor_dalam() faktor_dalam()

Keuntungan utama menggunakan pola seperti itu adalah dengan melakukan semua pemeriksaan argumen di fungsi luar, kita dapat dengan aman melewati pemeriksaan kesalahan di fungsi dalam dan fokus pada perhitungan saat ini.

Dasar-dasar penggunaan fungsi bersarang di Python

Enkapsulasi

Kasus penggunaan umum untuk fungsi internal adalah ketika Anda perlu melindungi atau menyembunyikan fungsi dari segala sesuatu yang terjadi di luarnya, yaitu menyembunyikan fungsi sepenuhnya dari lingkup global. Perilaku ini biasanya disebut sebagai enkapsulasi

Mari kita mulai dengan contoh ilustratif

def increment(number):
    def inner_increment():
        return number + 1
    return inner_increment()
 print(increment(10))

KELUARAN

11

# Let's call the nested function inner_increment()
>>> print(inner_increment())
_

KELUARAN

Kesalahan Nama. nama 'inner_increment' tidak ditentukan

Dalam contoh ini, kami tidak memiliki akses langsung ke. Dengan mencoba mengakses fungsi bersarang, kami mendapatkan. Fungsi menyembunyikan fungsi sepenuhnya, mencegah akses dari lingkup global. inner_increment() Kesalahan Nama increment() inner_increment()

Membuat fungsi pembantu internal

Terkadang kita membutuhkan sebuah fungsi yang mengeksekusi potongan kode yang sama di beberapa tempat di dalam tubuhnya. Mari kita ambil contoh untuk membuat fungsi untuk mengakses dan menggunakan file CSV yang berisi informasi tentang hotspot Nirkabel. Untuk mengetahui jumlah titik akses, serta informasi tentang perusahaan yang menyediakannya, kami membuat skrip berikut

import CSV
from collections import Counter
def process_hotspots(file):
    def most_common_provider(file_obj):
        hotspots = []
        with file_obj as csv_file:
            content = csv.DictReader(csv_file)
            for row in content:
                hotspots.append(row["Provider"])
        counter = Counter(hotspots)
        print(
             f "{counter.most_common (1) [0] [1]} provides"
             f "{counter.most_common (1) [0] [0]}."
        )
    if isinstance(file, str):
# Get the path to the file
                file_obj = open(file, "r")
        most_common_provider(file_obj)
    else:
        # We take the file object
        most_common_provider(file)

Ini membutuhkan argumen dan memeriksa apakah file tersebut adalah jalur string ke file fisik atau objek file. Fungsi tersebut kemudian memanggil fungsi dalam pembantu yang mengambil objek file dan melakukan operasi berikut. file process_hotspots() most_common_provider()

  1. Membaca konten file ke dalam generator yang membuat kamus menggunakan. CSV. DictReader

  2. Daftar penyedia Wi-Fi

  3. Menghitung jumlah hotspot Wi-Fi untuk setiap provider yang menggunakan fasilitas. koleksi. Menangkal

  4. Mencetak pesan dengan informasi yang diterima

Dengan menjalankan fungsi, kami mendapatkan output berikut

>>> from hotspots import process_hotspots
>>> file_obj = open ("./ NY_Wi-Fi_Hotspot_Locations.csv", "r")
>>> process_hotspots (file_obj)
There are 3,319 Wi-Fi points in New York.
1,868 of these are provided by LinkNY - City bridge.
>>> process_hotspots ("./ NY_Wi-Fi_Hotspot_Locations.csv")
There are 3,319 Wi-Fi points in New York.
1,868 of these are provided by LinkNY - City bridge.
_

Terlepas dari apakah kita memanggil dengan jalur file string atau objek file, Anda akan mendapatkan hasil yang sama. process_hotspots()

Menggunakan fungsi pembantu internal dan pribadi

Kami biasanya membuat fungsi internal pembantu, seperti saat kami ingin menyediakan enkapsulasi atau saat kami tidak akan memanggilnya di mana pun selain fungsi enklosur. kebanyakan_common_provider()

Meskipun menulis fungsi pembantu internal memberikan hasil yang diinginkan, biasanya yang terbaik adalah mengeksposnya sebagai fungsi tingkat atas. Dalam hal ini, Anda dapat menggunakan awalan garis bawah pada nama fungsi untuk menunjukkan bahwa itu bersifat pribadi untuk modul atau kelas saat ini. Untuk membuat kode lebih bersih dan mudah dibaca, kami menggunakan ekstraksi fungsi internal ke fungsi pribadi tingkat atas. Praktek ini sesuai dengan prinsip tanggung jawab tunggal

Menyimpan Status dengan Fungsi Bersarang. Penutupan dengan Python

Fungsi Python dalam haknya sama dengan objek lain, seperti angka, string, daftar, tupel, modul, dll. Artinya, mereka dapat dibuat atau dihancurkan secara dinamis, disimpan dalam struktur data, diteruskan sebagai argumen ke fungsi lain, digunakan sebagai nilai yang dikembalikan

Bagaimana Anda menulis fungsi di dalam fungsi python?

Sumber

Jika kita tidak perlu menyembunyikan fungsi internal dari dunia luar, maka tidak ada alasan khusus untuk bersarang

Di bagian ini, kita akan berbicara tentang jenis fungsi bersarang lainnya – penutupan. Ini adalah fungsi yang dibuat secara dinamis yang dikembalikan oleh fungsi lain. Untuk mengakses variabel dan nama yang ditentukan dalam penutupan namespace lokal memiliki hak penuh, tidak peduli apakah fungsi penutup telah selesai dieksekusi atau tidak

Ada tiga langkah untuk menentukan penutupan

  1. Buat fungsi bersarang

  2. Lihat variabel dari fungsi penutup

  3. Mengembalikan fungsi bersarang

Mari kita lihat beberapa contoh sekarang

Menyimpan negara dalam penutupan

Jadi, penutupan memaksa fungsi bersarang, saat dipanggil, untuk menyelamatkan keadaan lingkungannya. Artinya, ketertutupan tidak hanya fungsi internal itu sendiri tetapi juga lingkungan

Perhatikan contoh berikut

powers.py
def generate_power(exponent):
    def power(base):
        return base ** exponent
    return power

Di sini kita mendefinisikan fungsi yang merupakan pabrik untuk membuat penutupan. Artinya, fungsi ini membuat dan mengembalikan fungsi penutupan baru setiap kali dipanggil. Baris berikutnya mendefinisikan fungsi yang merupakan fungsi internal dan mengambil satu argumen dan mengembalikan hasil ekspresi. Baris terakhir kembali sebagai objek fungsi tanpa memanggilnya. generate_power() power() base base ** pangkat eksponen

Dari mana asal nilai eksponen? . Contoh ini mendapatkan nilai eksponen dari fungsi eksternal. Inilah yang dilakukan Python saat kita memanggil. power() eksponen power() generate_power() generate_power()

  1. Mendefinisikan instance baru yang membutuhkan argumen. kekuatan() dasar

  2. Mengambil "snapshot" lingkungan. Ini termasuk nilai saat ini. pangkat() eksponen

  3. Kembali bersama dengan negara bagian. kekuasaan()

Jadi, saat kita memanggil instance yang dikembalikan oleh fungsi, kita dapat melihat bahwa fungsi tersebut mengingat nilai derajat. power() generate_power() eksponen

>>> raise_two = generate_power(2)
>>> raise_three = generate_power(3)
>>> raise_two(4)
_

KELUARAN

16

>>> raise_two(5)
_

KELUARAN

25

def outer_func(who):
    def inner_func():
        print(f"Hello, {who}")
    inner_func()
outer_func("World!")
_0

KELUARAN

64

Perhatikan bahwa kedua penutupan mengingat eksponen yang sesuai di antara panggilan. Dalam contoh ini, mengingat apa , dan mengingat apa. kenaikan_dua() eksponen = 2 kenaikan_tiga() eksponen = 3

Mari pertimbangkan contoh lain

def outer_func(who):
    def inner_func():
        print(f"Hello, {who}")
    inner_func()
outer_func("World!")
1
def outer_func(who):
    def inner_func():
        print(f"Hello, {who}")
    inner_func()
outer_func("World!")
2

KELUARAN

'admin' memiliki akses ke Halaman Admin

def outer_func(who):
    def inner_func():
        print(f"Hello, {who}")
    inner_func()
outer_func("World!")
_3

KELUARAN

'john' tidak memiliki akses ke Halaman Admin

Fungsi bersarang memeriksa apakah pengguna tertentu memiliki hak akses yang diperlukan ke halaman. Alih-alih memeriksa apakah pengguna sama, Anda dapat menanyakan database. 'admin'

Penutupan biasanya tidak mengubah keadaan yang mereka terima saat lahir, seperti yang ditunjukkan pada contoh di atas. Tapi Anda juga bisa membuat penutupan dinamis menggunakan objek yang bisa berubah seperti kamus, kumpulan, atau daftar

Misalkan Anda ingin menghitung rata-rata untuk kumpulan data. Data datang dalam bentuk aliran pengukuran berturut-turut dari parameter yang dianalisis, dan fungsi perlu mempertahankan pengukuran sebelumnya di antara panggilan. Dalam hal ini, kode pabrik untuk membuat penutupan mungkin terlihat seperti ini

def outer_func(who):
    def inner_func():
        print(f"Hello, {who}")
    inner_func()
outer_func("World!")
_4

Penutupan yang ditetapkan mempertahankan status pengambilan di antara panggilan. Meskipun kami mendefinisikan daftar secara internal, itu juga tersedia dalam penutupan. sampel_rata-rata sampel rata-rata()

Mengubah status gertakan

Variabel penutupan biasanya benar-benar tersembunyi dari dunia luar. Namun, kita dapat mendefinisikan fungsi getter dan setter untuk mereka

def outer_func(who):
    def inner_func():
        print(f"Hello, {who}")
    inner_func()
outer_func("World!")
_5

Di sini mengembalikan penutupan yang mewakili objek. Fungsi dilampirkan ke objek ini yang dapat kita gunakan untuk mendapatkan akses untuk membaca dan menulis variabel dan. make_point() titik x y

Pabrik semacam itu bahkan mungkin lebih cepat daripada kelas yang setara, tetapi pendekatannya tidak memberikan pewarisan, deskriptor, dan fitur lain dari kelas Python

Mengubah Perilaku dengan Fungsi Bersarang. Dekorator

Dekorator Python adalah kasus penggunaan populer dan mudah berikutnya untuk fungsi internal, terutama untuk penutupan. Dekorator adalah fungsi tingkat tinggi yang menggunakan objek yang dapat dipanggil (fungsi, metode, kelas) sebagai argumen dan mengembalikan objek lain yang dapat dipanggil

Bagaimana Anda menulis fungsi di dalam fungsi python?

Sumber

Biasanya, dekorator digunakan untuk menambahkan properti secara dinamis ke callee yang ada dan memperluas perilakunya secara transparan tanpa memengaruhi atau memodifikasi callee. Fungsi dekorator dapat diterapkan ke objek apa pun yang dapat dipanggil. Untuk melakukan ini, simbol dan nama dekorator ditempatkan di baris sebelumnya

def outer_func(who):
    def inner_func():
        print(f"Hello, {who}")
    inner_func()
outer_func("World!")
_6

lulus

Sintaks ini memaksa Anda untuk menerimanya secara otomatis sebagai argumen dan memprosesnya di tubuh Anda. Operasi ini merupakan singkatan dari pernyataan seperti ini. dekorator() dekorator_fungsi()

dekorasi_fungsi = penghias(fungsi_hiasi)

Berikut adalah contoh bagaimana Anda dapat membuat fungsi dekorator untuk mengubah perilaku fungsi yang sudah ada

def outer_func(who):
    def inner_func():
        print(f"Hello, {who}")
    inner_func()
outer_func("World!")
_7

KELUARAN

Halo Dunia

Dalam contoh ini, kami menggunakan fungsi untuk menghias. Akibatnya, fungsi mendapatkan fungsionalitas baru. Sekarang, saat kita menelepon, alih-alih hanya mengetik, itu mencetak dua pesan tambahan. @add_messages salam() salam() Halo Dunia

Praktik paling sederhana untuk men-debug kode Python adalah memasukkan panggilan untuk memeriksa nilai variabel. Namun, dengan menambah dan menghapus panggilan, kami berisiko melupakan beberapa di antaranya. Untuk mencegah situasi ini, kita dapat menulis dekorator berikut. cetak() cetak()

def outer_func(who):
    def inner_func():
        print(f"Hello, {who}")
    inner_func()
outer_func("World!")
_8

Dalam contoh ini, fungsi dekorator mencetak nama fungsi untuk menghias, nilai saat ini dari setiap argumen, dan hasil pengembalian. Dekorator semacam itu dapat digunakan untuk debugging fungsi dasar. Setelah kami mendapatkan hasil yang diinginkan, cukup untuk menghapus panggilan ke dekorator, dan fungsi yang di-debug akan berfungsi seperti biasa. debug() @debug

Mari berikan contoh terakhir dan terapkan kembali sebagai fungsi dekorator. generate_power()

def outer_func(who):
    def inner_func():
        print(f"Hello, {who}")
    inner_func()
outer_func("World!")
_9

Versi ini memberikan hasil yang sama dengan implementasi aslinya. Dalam hal ini, untuk menyimpan eksponen. generate_power() func() dalam versi modifikasi kami menggunakan penutupan dan juga dekorator

Di sini dekorator harus mengambil argumen (eksponen), jadi kami membutuhkan dua tingkat penyarangan. Tingkat pertama diwakili oleh fungsi yang menggunakan fungsi untuk menghias sebagai argumen. Tingkat kedua diwakili oleh fungsi yang mengemas eksponen ke dalam, melakukan perhitungan akhir, dan mengembalikan hasilnya. power() inner_power() argumen

Kesimpulan

Jadi, di Python, fungsi bersarang memiliki akses langsung ke variabel dan nama yang Anda tetapkan di fungsi terlampir. Ini menyediakan mekanisme untuk mengenkapsulasi fungsi, membuat solusi pembantu, dan mengimplementasikan penutupan dan dekorator

Media yang ditampilkan dalam artikel ini bukan milik Analytics Vidhya dan digunakan atas kebijaksanaan Penulis

Bagaimana Anda membuat fungsi di dalam suatu fungsi?

Pendekatan. .
Tulis satu fungsi di dalam fungsi lain
Lakukan panggilan ke fungsi dalam di pernyataan pengembalian fungsi luar
Sebut saja fun(a)(b) di mana a adalah parameter ke luar dan b ke fungsi dalam
Terakhir, kembalikan output gabungan dari fungsi bersarang

Bagaimana Anda melewatkan fungsi di dalam fungsi dengan Python?

fungsi adalah objek kelas satu di python. Anda dapat membagikannya, memasukkannya ke dalam dikte, daftar, dll. Hanya jangan sertakan tanda kurung setelah nama fungsi . Contoh, untuk fungsi bernama myfunction. myfunction berarti fungsi itu sendiri, myfunction() berarti memanggil fungsi dan mendapatkan nilai pengembaliannya.

Bisakah Anda melakukan fungsi di dalam fungsi?

Memanggil fungsi dari dalam dirinya sendiri disebut rekursi dan jawaban sederhananya adalah, ya.

Bagaimana Anda membuat fungsi bersarang di Python?

Mendefinisikan Fungsi Bersarang . Ini sebuah contoh. Kami mendefinisikan fungsi bernama inner() di dalam fungsi lain bernama outer(). Jadi, inner() adalah fungsi bersarang. creating it using the def keyword inside another function. Here is an example. We defined a function named inner() inside another function named outer() . Thus, inner() is a nested function.