Μπορείτε να εξηγήσετε το κλείσιμο (που σχετίζονται με Python);

ψήφοι
67

Έχω διαβάσει πολλά για το κλείσιμο και νομίζω ότι τους καταλαβαίνουν, χωρίς όμως να δυσκολεύει την εικόνα για τον εαυτό μου και τους άλλους, ελπίζω κάποιος μπορεί να εξηγήσει το κλείσιμο, όπως συνοπτικά και με σαφήνεια το δυνατόν περισσότερο. Ψάχνω για μια απλή εξήγηση που θα μπορούσε να με βοηθήσει να καταλάβω πού και γιατί θα ήθελα να τα χρησιμοποιούν.

Δημοσιεύθηκε 17/08/2008 στις 20:14
πηγή χρήστη
Σε άλλες γλώσσες...                            


13 απαντήσεις

ψήφοι
42

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

>>> def makeConstantAdder(x):
...     constant = x
...     def adder(y):
...         return y + constant
...     return adder
... 
>>> f = makeConstantAdder(12)
>>> f(3)
15
>>> g = makeConstantAdder(4)
>>> g(3)
7

Να σημειωθεί ότι 12 και 4 έχουν «εξαφανιστεί» μέσα στ και ζ, αντίστοιχα, το χαρακτηριστικό αυτό είναι ό, τι κάνουν στ και ζ σωστή κλείσιμο.

Απαντήθηκε 17/08/2008 στις 20:32
πηγή χρήστη

ψήφοι
6

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

Αυτό λέγεται ένα κλείσιμο, διότι «κλείνει πάνω» στο εξωτερικό μεταβλητή (σταθερή) - δηλαδή, δεν είναι μόνο μια λειτουργία, αλλά ένα περίβλημα του περιβάλλοντος στο οποίο δημιουργήθηκε η λειτουργία.

Στο ακόλουθο παράδειγμα, καλώντας το κλείσιμο g μετά την αλλαγή x θα αλλάξει επίσης την τιμή του x εντός g, δεδομένου g κλείνει πάνω x:

x = 0

def f():
    def g(): 
        return x * 2
    return g


closure = f()
print(closure()) # 0
x = 2
print(closure()) # 4
Απαντήθηκε 17/08/2008 στις 21:20
πηγή χρήστη

ψήφοι
14

Μου αρέσει αυτό το τραχύ, συνοπτικό ορισμό :

Μια λειτουργία που μπορεί να αναφέρονται σε περιβάλλοντα που δεν είναι πλέον ενεργή.

Θα προσθέσω

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

Διακοσμητές που δέχονται οι παράμετροι είναι μια κοινή χρήση για το κλείσιμο. Πώματα είναι ένα κοινό μηχανισμό εφαρμογής για αυτό το είδος της «εργοστάσιο λειτουργία». Έχω συχνά επιλέγουν να χρησιμοποιήσουν το κλείσιμο της Μοτίβο στρατηγική όταν η στρατηγική είναι τροποποιημένο από τα στοιχεία κατά το χρόνο εκτέλεσης.

Σε μια γλώσσα που επιτρέπει την ανώνυμη ορισμό μπλοκ - π.χ., Ruby, C # - κλεισίματα μπορεί να χρησιμοποιηθεί για την υλοποίηση (ποιο ποσό) μυθιστόρημα νέες δομές ελέγχου. Η έλλειψη των ανώνυμων μπλοκ είναι μεταξύ τους περιορισμούς των κλεισιμάτων στην Python .

Απαντήθηκε 17/08/2008 στις 21:25
πηγή χρήστη

ψήφοι
13

Για να είμαι ειλικρινής, έχω καταλάβει το κλείσιμο πάρα πολύ καλά, εκτός από Δεν έχω πάει ποτέ σαφής για το τι ακριβώς είναι το πράγμα που είναι το «κλείσιμο» και τι είναι τόσο «κλείσιμο» γι 'αυτό. Θα σας συνιστούσαμε να εγκαταλείψουν ψάχνει για οποιαδήποτε λογική πίσω από την επιλογή του όρου.

Τέλος πάντων, εδώ είναι εξήγηση μου:

def foo():
   x = 3
   def bar():
      print x
   x = 5
   return bar

bar = foo()
bar()   # print 5

Μια βασική ιδέα εδώ είναι ότι το αντικείμενο λειτουργία επέστρεψε από την foo διατηρεί ένα γάντζο στο τοπικό var «x», ακόμη και αν «x» μπήκε στον αγωνιστικό χώρο του πεδίου εφαρμογής και θα πρέπει να είναι ανενεργή. Αυτό το άγκιστρο είναι στο ίδιο το var, όχι μόνο η αξία που var είχε εκείνη την εποχή, έτσι όταν bar ονομάζεται, τυπώνει 5, όχι 3.

Επίσης, είναι σαφές ότι η Python 2.x έχει περιορίσει το κλείσιμο: δεν υπάρχει κανένας τρόπος που μπορώ να τροποποιήσει εντός «γραμμή» «χ», επειδή το γράψιμο «x = μπλα», θα κηρύξει μια τοπική «x» στο μπαρ, να μην αναθέσει σε «x» παπο . Αυτό είναι μια παρενέργεια της εκχώρησης = δήλωση της Python. Για να πάρετε γύρω από αυτό, Python 3.0 εισάγει το μη τοπικό λέξη-κλειδί:

def foo():
   x = 3
   def bar():
      print x
   def ack():
      nonlocal x
      x = 7
   x = 5
   return (bar, ack)

bar, ack = foo()
ack()   # modify x of the call to foo
bar()   # print 7
Απαντήθηκε 23/08/2008 στις 08:43
πηγή χρήστη

ψήφοι
-2

Η καλύτερη εξήγηση που είδα ποτέ από το κλείσιμο ήταν να εξηγήσει τον μηχανισμό. Πήγε κάτι σαν αυτό:

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

Τώρα χαλαρώστε τον περιορισμό ότι κάθε κόμβος μπορεί να έχει μόνο ένα παιδί.

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

Απαντήθηκε 18/09/2008 στις 18:10
πηγή χρήστη

ψήφοι
75

Κλείσιμο για κλείσιμο

Τα αντικείμενα είναι στοιχεία με τις μεθόδους που επισυνάπτεται, κλεισίματα οι λειτουργίες με τα δεδομένα που επισυνάπτεται.

def make_counter():
    i = 0
    def counter(): # counter() is a closure
        nonlocal i
        i += 1
        return i
    return counter

c1 = make_counter()
c2 = make_counter()

print (c1(), c1(), c2(), c2())
# -> 1 2 1 2
Απαντήθηκε 26/09/2008 στις 20:28
πηγή χρήστη

ψήφοι
3

Εδώ είναι μια τυπική περίπτωση χρήσης για το κλείσιμο - callbacks για τα στοιχεία GUI (αυτό θα ήταν μια εναλλακτική λύση για υποκλάσεις της κλάσης κουμπί). Για παράδειγμα, μπορείτε να δημιουργήσετε μια συνάρτηση που θα κληθεί ως απάντηση σε ένα πατήστε το κουμπί και «κλείνει» κατά τη διάρκεια των σχετικών μεταβλητών στη μητρική πεδίο που είναι απαραίτητα για την επεξεργασία των κλικ. Με αυτό τον τρόπο μπορείτε να συνδέσετε έως και αρκετά περίπλοκο διασυνδέσεις από την ίδια λειτουργία προετοιμασίας, με βάση όλες τις εξαρτήσεις στο κλείσιμο.

Απαντήθηκε 23/01/2009 στις 17:13
πηγή χρήστη

ψήφοι
0

Για μένα, «κλείσιμο» είναι συναρτήσεις οι οποίες είναι ικανές να θυμόμαστε το περιβάλλον που δημιουργήθηκαν. Αυτή η λειτουργία, σας επιτρέπει να χρησιμοποιήσετε μεταβλητές ή τις μεθόδους εντός του διασκορπισμένες κλείσιμο, με άλλο τρόπο, δεν θα είναι σε θέση να χρησιμοποιήσει είτε επειδή δεν υπάρχουν πια ή είναι μακριά λόγω πεδίο. Ας ρίξουμε μια ματιά σε αυτόν τον κώδικα σε Ruby:

def makefunction (x)
  def multiply (a,b)
    puts a*b
  end
  return lambda {|n| multiply(n,x)} # => returning a closure
end

func = makefunction(2) # => we capture the closure
func.call(6)    # => Result equal "12"  

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

Απαντήθηκε 20/09/2013 στις 14:39
πηγή χρήστη

ψήφοι
1

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

Στην πραγματικότητα, το μοντέλο δεδομένων εξηγεί αυτό στην περιγραφή του λειτουργιών __closure__χαρακτηριστικό:

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

Για να αποδειχθεί αυτό:

def enclosure(foo):
    def closure(bar):
        print(foo, bar)
    return closure

closure_instance = enclosure('foo')

Προφανώς, γνωρίζουμε ότι έχουμε τώρα μια λειτουργία στραμμένο από το όνομα της μεταβλητής closure_instance. Φαινομενικά, αν το ονομάζουμε με ένα αντικείμενο, barθα πρέπει να εκτυπώσετε το string, 'foo'και ό, τι η αναπαράσταση σειρά barείναι.

Στην πραγματικότητα, η συμβολοσειρά «foo» είναι δεσμευμένο στο παράδειγμα της λειτουργίας, και μπορούμε να το διαβάσει απευθείας εδώ, από την πρόσβαση στο cell_contentsχαρακτηριστικό της πρώτης (και μόνο) κύτταρο στο πλειάδα του __closure__χαρακτηριστικού:

>>> closure_instance.__closure__[0].cell_contents
'foo'

Ως μέρος, οι κυτταρικές αντικείμενα περιγράφονται στην τεκμηρίωση C API:

Τα «τηλέφωνα» αντικείμενα που χρησιμοποιούνται για την υλοποίηση των μεταβλητών αναφέρεται από πολλούς πεδία

Και μπορούμε να αποδείξει τη χρήση κλεισίματος μας, σημειώνοντας ότι 'foo'έχει κολλήσει στη λειτουργία και δεν αλλάζει:

>>> closure_instance('bar')
foo bar
>>> closure_instance('baz')
foo baz
>>> closure_instance('quux')
foo quux

Και τίποτα δεν μπορεί να αλλάξει:

>>> closure_instance.__closure__ = None
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: readonly attribute

μερική Λειτουργίες

Το παράδειγμα που δίνεται χρησιμοποιεί το κλείσιμο ως μερική λειτουργία, αλλά αν αυτό είναι μόνο στόχος μας, η ίδια στόχος μπορεί να επιτευχθεί με functools.partial

>>> from __future__ import print_function # use this if you're in Python 2.
>>> partial_function = functools.partial(print, 'foo')
>>> partial_function('bar')
foo bar
>>> partial_function('baz')
foo baz
>>> partial_function('quux')
foo quux

Υπάρχουν πιο περίπλοκη κλείσιμο, καθώς και ότι δεν θα ταιριάζει με την μερική παράδειγμα λειτουργίας, και θα τους αποδείξουν περαιτέρω ο χρόνος το επιτρέπει.

Απαντήθηκε 18/07/2014 στις 04:33
πηγή χρήστη

ψήφοι
1

Εδώ είναι ένα παράδειγμα του κλεισίματος python3

def closure(x):
    def counter():
        nonlocal x
        x += 1
        return x
    return counter;

counter1 = closure(100);
counter2 = closure(200);

print("i from closure 1 " + str(counter1()))
print("i from closure 1 " + str(counter1()))
print("i from closure 2 " + str(counter2()))
print("i from closure 1 " + str(counter1()))
print("i from closure 1 " + str(counter1()))
print("i from closure 1 " + str(counter1()))
print("i from closure 2 " + str(counter2()))

# result

i from closure 1 101
i from closure 1 102
i from closure 2 201
i from closure 1 103
i from closure 1 104
i from closure 1 105
i from closure 2 202
Απαντήθηκε 22/09/2015 στις 20:16
πηγή χρήστη

ψήφοι
0
# A Closure is a function object that remembers values in enclosing scopes even if they are not present in memory.

# Defining a closure

# This is an outer function.
def outer_function(message):
    # This is an inner nested function.
    def inner_function():
        print(message)
    return inner_function

# Now lets call the outer function and return value bound to name 'temp'
temp = outer_function("Hello")
# On calling temp, 'message' will be still be remembered although we had finished executing outer_function()
temp()
# Technique by which some data('message') that remembers values in enclosing scopes 
# even if they are not present in memory is called closures

# Output: Hello

Κριτήρια για να πληρούνται από το κλείσιμο είναι:

  1. Πρέπει να έχουμε ένθετη λειτουργία.
  2. Ένθετη συνάρτηση πρέπει να αναφέρεται στην τιμή που ορίζεται στη λειτουργία που περικλείει.
  3. συνάρτηση που περικλείει πρέπει να επιστρέψει το ένθετο λειτουργία.

# Example 2
def make_multiplier_of(n): # Outer function
    def multiplier(x): # Inner nested function
        return x * n
    return multiplier
# Multiplier of 3
times3 = make_multiplier_of(3)
# Multiplier of 5
times5 = make_multiplier_of(5)
print(times5(3)) # 15
print(times3(2)) #  6
Απαντήθηκε 26/12/2017 στις 16:41
πηγή χρήστη

ψήφοι
0

όλοι έχουν χρησιμοποιήσει Διακοσμητές σε python. Είναι ωραία παραδείγματα για να δείξει ποιες είναι οι λειτουργίες κλεισίματος σε python.

class Test():
    def decorator(func):
        def wrapper(*args):
            b = args[1] + 5
            return func(b)
        return wrapper

@decorator
def foo(val):
    print val + 2

obj = Test()
obj.foo(5)

Εδώ τελική τιμή είναι 12

Εδώ, η λειτουργία περιτύλιγμα είναι σε θέση να έχουν πρόσβαση αντικείμενο func λόγω περιτύλιγμα είναι «λεξιλογικό κλείσιμο», μπορεί να έχει πρόσβαση είναι η μητρική χαρακτηριστικά. Γι 'αυτό, είναι σε θέση να έχουν πρόσβαση αντικείμενο func.

Απαντήθηκε 17/04/2018 στις 19:00
πηγή χρήστη

ψήφοι
0

Θα ήθελα να μοιραστώ το παράδειγμα μου και μια εξήγηση για το κλείσιμο. Έκανα ένα παράδειγμα python, και τα δύο στοιχεία για να αποδείξει κράτη στοίβα.

def maker(a, b, n):
    margin_top = 2
    padding = 4
    def message(msg):
        print('\n’ * margin_top, a * n, 
            ' ‘ * padding, msg, ' ‘ * padding, b * n)
    return message

f = maker('*', '#', 5)
g = maker('', '♥’, 3)
f('hello')
g(‘good bye!')

Η έξοδος αυτού του κώδικα θα είναι ως εξής:

*****      hello      #####

      good bye!    ♥♥♥

Εδώ είναι δύο στοιχεία που να δείχνουν στοίβες και το κλείσιμο συνδέονται με το αντικείμενο λειτουργίας.

όταν η λειτουργία επιστρέφει από την κατασκευάστρια

όταν η λειτουργία αυτή ονομάζεται αργότερα

Όταν η λειτουργία καλείται μέσω μια παράμετρο ή ένα μη τοπικό μεταβλητή, ο κώδικας χρειάζεται τοπική δέστρες μεταβλητής όπως margin_top, παραγέμισμα καθώς και ένα, b, n. Προκειμένου να διασφαλιστεί η λειτουργία κωδικού στην εργασία, το πλαίσιο της στοίβας της συνάρτησης maker που είχε φύγει πριν από λίγο καιρό θα πρέπει να είναι προσβάσιμες, η οποία υποστηρίζεται στο κλείσιμο μπορούμε να βρούμε μαζί με αντικείμενο τη λειτουργία του το μήνυμα «του.

Απαντήθηκε 12/05/2018 στις 04:17
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more