Python Closures: Πώς να το χρησιμοποιήσετε και γιατί;

Σε αυτό το σεμινάριο, θα μάθετε για το κλείσιμο Python, πώς να ορίσετε ένα κλείσιμο και τους λόγους που πρέπει να το χρησιμοποιήσετε.

Μη τοπική μεταβλητή σε ένθετη συνάρτηση

Πριν μπείτε σε αυτό το κλείσιμο, πρέπει πρώτα να καταλάβουμε τι είναι μια ένθετη συνάρτηση και μη τοπική μεταβλητή

Μια συνάρτηση που ορίζεται σε μια άλλη συνάρτηση ονομάζεται ένθετη συνάρτηση. Οι ένθετες συναρτήσεις μπορούν να έχουν πρόσβαση σε μεταβλητές του εύρους που περικλείουν.

Στο Python, αυτές οι μη τοπικές μεταβλητές είναι μόνο για ανάγνωση από προεπιλογή και πρέπει να τις δηλώσουμε ρητά ως μη τοπικές (χρησιμοποιώντας μη τοπική λέξη-κλειδί) για να τις τροποποιήσουμε.

Ακολουθεί ένα παράδειγμα μιας ένθετης συνάρτησης που αποκτά πρόσβαση σε μια μη τοπική μεταβλητή.

 def print_msg(msg): # This is the outer enclosing function def printer(): # This is the nested function print(msg) printer() # We execute the function # Output: Hello print_msg("Hello")

Παραγωγή

 Χαίρετε

Μπορούμε να δούμε ότι η ένθετη printer()συνάρτηση μπόρεσε να αποκτήσει πρόσβαση στη μη τοπική μεταβλητή msg της συνάρτησης.

Καθορισμός συνάρτησης κλεισίματος

Στο παραπάνω παράδειγμα, τι θα συνέβαινε εάν η τελευταία γραμμή της συνάρτησης print_msg()επέστρεψε τη printer()συνάρτηση αντί να την καλέσει; Αυτό σημαίνει ότι η συνάρτηση ορίστηκε ως εξής:

 def print_msg(msg): # This is the outer enclosing function def printer(): # This is the nested function print(msg) return printer # returns the nested function # Now let's try calling this function. # Output: Hello another = print_msg("Hello") another()

Παραγωγή

 Χαίρετε

Αυτό είναι ασυνήθιστο.

Η print_msg()συνάρτηση κλήθηκε με τη συμβολοσειρά "Hello"και η επιστρεφόμενη συνάρτηση δεσμεύτηκε στο όνομα άλλου. Κατά την κλήση another(), το μήνυμα θυμόταν ακόμα αν και είχαμε ήδη ολοκληρώσει την εκτέλεση της print_msg()λειτουργίας.

Αυτή η τεχνική με την οποία ορισμένα δεδομένα ( "Helloσε αυτήν την περίπτωση) συνδέονται με τον κωδικό ονομάζεται κλείσιμο στο Python .

Αυτή η τιμή στο εύρος συνημμένων θυμάται ακόμα και όταν η μεταβλητή βγαίνει εκτός πεδίου ή η ίδια η συνάρτηση αφαιρείται από τον τρέχοντα χώρο ονομάτων.

Δοκιμάστε να εκτελέσετε τα ακόλουθα στο κέλυφος Python για να δείτε την έξοδο.

 >>> del print_msg >>> another() Hello >>> print_msg("Hello") Traceback (most recent call last):… NameError: name 'print_msg' is not defined

Εδώ, η επιστρεφόμενη λειτουργία εξακολουθεί να λειτουργεί ακόμη και όταν η αρχική συνάρτηση διαγράφηκε.

Πότε έχουμε κλείσιμο;

Όπως φαίνεται από το παραπάνω παράδειγμα, έχουμε ένα κλείσιμο στο Python όταν μια ένθετη συνάρτηση αναφέρεται σε μια τιμή στο περίβλημα.

Τα κριτήρια που πρέπει να πληρούνται για τη δημιουργία κλεισίματος στο Python συνοψίζονται στα ακόλουθα σημεία.

  • Πρέπει να έχουμε μια ένθετη συνάρτηση (λειτουργία μέσα σε μια συνάρτηση).
  • Η ένθετη συνάρτηση πρέπει να αναφέρεται σε μια τιμή που ορίζεται στη συνάρτηση εγκλεισμού.
  • Η συνάρτηση κλεισίματος πρέπει να επιστρέψει την ένθετη συνάρτηση.

Πότε να χρησιμοποιήσετε το κλείσιμο;

Για ποιο λόγο είναι καλό το κλείσιμο;

Το κλείσιμο μπορεί να αποφύγει τη χρήση καθολικών τιμών και παρέχει κάποια μορφή απόκρυψης δεδομένων. Μπορεί επίσης να παρέχει μια αντικειμενοστραφή λύση στο πρόβλημα.

Όταν υπάρχουν λίγες μέθοδοι (μία μέθοδος στις περισσότερες περιπτώσεις) που πρέπει να εφαρμοστούν σε μια τάξη, το κλείσιμο μπορεί να προσφέρει μια εναλλακτική και πιο κομψή λύση. Αλλά όταν ο αριθμός των χαρακτηριστικών και των μεθόδων μεγαλώνει, είναι καλύτερο να εφαρμόσετε μια τάξη.

Εδώ είναι ένα απλό παράδειγμα όπου ένα κλείσιμο μπορεί να είναι προτιμότερο από τον ορισμό μιας κλάσης και την κατασκευή αντικειμένων. Αλλά η προτίμηση είναι δική σας.

 def make_multiplier_of(n): def multiplier(x): return x * n return multiplier # Multiplier of 3 times3 = make_multiplier_of(3) # Multiplier of 5 times5 = make_multiplier_of(5) # Output: 27 print(times3(9)) # Output: 15 print(times5(3)) # Output: 30 print(times5(times3(2)))

Παραγωγή

 27 15 30

Οι Python Decorators κάνουν εκτεταμένη χρήση κλεισίματος.

Εν κατακλείδι, είναι καλό να επισημάνουμε ότι μπορούν να βρεθούν οι τιμές που περικλείονται στη λειτουργία κλεισίματος.

Όλα τα αντικείμενα συνάρτησης έχουν ένα __closure__χαρακτηριστικό που επιστρέφει μια πλειάδα αντικειμένων κελιού εάν είναι συνάρτηση κλεισίματος. Αναφερόμενος στο παραπάνω παράδειγμα, γνωρίζουμε times3και times5είναι λειτουργίες κλεισίματος.

 >>> make_multiplier_of.__closure__ >>> times3.__closure__ (,)

Το αντικείμενο κελιού έχει το χαρακτηριστικό cell_contents που αποθηκεύει την κλειστή τιμή.

 >>> times3.__closure__(0).cell_contents 3 >>> times5.__closure__(0).cell_contents 5

ενδιαφέροντα άρθρα...