Κλεισίματα στην Python
Με τον όρο κλείσιμο (closure) εννοούμε μια συνάρτηση μαζί με όλες τις εξωτερικές μεταβλητές που είναι προσβάσιμες σε αυτήν.
Στην Python, τις περισσότερες φορές, όταν λέμε "κλείσιμο συνάρτησης", δεν εννοούμε την ίδια τη συνάρτηση, αλλά ακριβώς τις εξωτερικές της μεταβλητές.
Ας υποθέσουμε ότι έχουμε την ακόλουθη συνάρτηση outer,
στην οποία δηλώνεται μια μεταβλητή i και
μια εσωτερική συνάρτηση inner. Σε αυτήν, στο
i θα προστίθεται μια μονάδα. Για να
λειτουργεί σωστά η μεταβλητή i,
προσθέτουμε σε αυτήν την εντολή nonlocal:
def outer():
i = 0
def inner():
nonlocal i
i += 1
print(i)
return inner
Τώρα ας βάλουμε την εξωτερική συνάρτηση σε
μια μεταβλητή res και ας την καλέσουμε με
στρογγυλές αγκύλες:
res = outer()
res() # θα τυπώσει 1
Ας καλέσουμε την res αρκετές φορές.
Μετά την εκτέλεση του κώδικα κάθε φορά ο μετρητής
i θα αυξάνεται κατά μία μονάδα:
res() # θα τυπώσει 2
res() # θα τυπώσει 3
res() # θα τυπώσει 4
Ωστόσο, υπάρχει μια σημαντική λεπτή διαφορά εδώ - κάθε
κλήση της συνάρτησης outer θα αυξάνει
τον δικό της μετρητή. Ας γράψουμε την πρώτη κλήση της outer
στη μεταβλητή res1, και τη δεύτερη
κλήση - στη μεταβλητή res2. Στη συνέχεια
ας τις τυπώσουμε στη κονσόλα διαδοχικά:
res1 = outer()
res1() # θα τυπώσει 1
res1() # θα τυπώσει 2
res1() # θα τυπώσει 3
res2 = outer()
res2() # θα τυπώσει 1
res2() # θα τυπώσει 2
res2() # θα τυπώσει 3
Δίνεται ο ακόλουθος κώδικας:
def outer():
i = 10
def inner():
nonlocal i
i -= 2
print(i)
return inner
res1 = outer()
res1()
res1()
res2 = outer()
res2()
res2()
res2()
Πείτε, τι θα τυπωθεί στην κονσόλα.
Φτιάξτε μια συνάρτηση, κάθε κλήση της οποίας θα επιστρέφει τον επόμενο αριθμό Fibonacci.
Φτιάξτε μια συνάρτηση, που θα δίνει έναν τυχαίο ακέραιο αριθμό σε ένα διάστημα, αλλά έτσι ώστε να μην εμφανίζεται δύο φορές στη σειρά ο ίδιος αριθμός.