Как зайти в Даркнет?!
25th January, 01:11
6
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
895
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
914
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4351
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4396
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Можете ли вы объяснить closures (как они соотносятся с Python)?
Я много читал о closures и думаю, что понимаю их, но, не затуманивая картину для себя и других, я надеюсь, что кто-то сможет объяснить closures настолько кратко и ясно, насколько это возможно. Я ищу простое объяснение, которое могло бы помочь мне понять, где и почему я хотел бы их использовать.
Это просто: функция, которая ссылается на переменные из содержащей области, потенциально после того, как flow-of-control покинет эту область. Этот последний бит очень полезен:
>>> 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 имеют "disappeared" внутри f и g, соответственно, эта функция является тем, что делает f и g правильными closures.
Честно говоря, я прекрасно понимаю closures, за исключением того, что я никогда не был ясен, что именно является вещью, которая является "closure", и что в ней так "closure". Я рекомендую вам отказаться от поиска какой-либо логики в выборе термина.
В любом случае, вот мое объяснение:
def foo():
x = 3
def bar():
print x
x = 5
return bar
bar = foo()
bar() # print 5
Ключевая идея здесь заключается в том, что объект функции, возвращаемый из foo, сохраняет крюк к локальному var 'x', даже если 'x' вышел из области видимости и должен быть отключен. Этот крючок относится к самому var, а не только к значению, которое var имел в то время, поэтому при вызове бара он выводит 5, а не 3.
Также ясно, что Python 2.x имеет ограниченное закрытие: я не могу изменить 'x' внутри 'bar', потому что написание 'x = bla' объявит локальный 'x' в баре, а не назначит 'x' из foo. Это побочный эффект объявления 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
Мне нравится это грубое, лаконичное определение :
Функция, которая может ссылаться на среды, которые больше не активны.
Я бы добавил
Замыкание позволяет связать переменные в функцию, не передавая их в качестве параметров .
Декораторы, которые принимают параметры, обычно используются для closures. Closures являются общим механизмом реализации для такого рода "function factory". Я часто использую closures в шаблоне стратегии , когда стратегия модифицируется данными во время выполнения.
В языке, который позволяет анонимное определение блока-например, Ruby, C# -- closures может быть использован для реализации (что означает) новых новых структур управления. Отсутствие анонимных блоков является одним из ограничений closures в Python .
Я никогда не слышал, чтобы транзакции использовались в том же контексте, что и объяснение того, что такое закрытие, и здесь действительно нет никакой семантики транзакций.
Это называется замыканием, потому что оно "closes over" внешняя переменная (константа) - то есть это не просто функция, а оболочка среды, в которой была создана функция.
В следующем примере вызов закрытия 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
Вот типичный пример использования для closures-обратных вызовов для GUI элементов (это было бы альтернативой подклассу класса button). Например, можно построить функцию, которая будет вызываться в ответ на нажатие кнопки, и "close" над соответствующими переменными в родительской области, которые необходимы для обработки щелчка. Таким образом, вы можете подключить довольно сложные интерфейсы из одной и той же функции инициализации, собрав все зависимости в замыкание.
В Python замыкание-это экземпляр функции, которая имеет переменные, связанные с ней неизменно.
Фактически, модель данных объясняет это в своем описании атрибута функций ' __closure__ :
Нет или кортеж ячеек , содержащих привязки для свободных переменных функции. Только для чтения
Продемонстрировать это:
def enclosure(foo):
def closure(bar):
print(foo, bar)
return closure
closure_instance = enclosure('foo')
Очевидно, мы знаем, что теперь у нас есть функция, указанная на переменную с именем closure_instance . Якобы, если мы вызовем его с помощью объекта bar, он должен вывести строку 'foo' и независимо от того, что представляет собой строковое представление bar .
Фактически, строка 'foo' привязана к экземпляру функции, и мы можем непосредственно прочитать ее здесь, обратившись к атрибуту cell_contents первой (и единственной) ячейки в кортеже атрибута __closure__ :
>>> closure_instance.__closure__[0].cell_contents
'foo'
Кроме того, объекты ячеек описаны в документации C API:
"Cell" объекты используются для реализации переменных, на которые ссылается несколько масштабы
И мы можем продемонстрировать использование нашего закрытия, отметив, что '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
Есть и более сложные closures, которые не подходят для примера частичной функции, и я продемонстрирую их дальше, как только позволит время.
Вот пример Python3 closures
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
# 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
# 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
Критерии, которым должен соответствовать Closures::
- Мы должны иметь вложенную функцию.
- Вложенная функция должна ссылаться на значение, определенное в заключающей функции.
- Заключающая функция должна возвращать вложенную функцию.
# 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
Для меня "closures"-это функции, которые способны запоминать среду, в которой они были созданы. Эта функциональность позволяет вам использовать переменные или методы в закрытии, которые, в противном случае, вы не сможете использовать либо потому, что они больше не существуют, либо они недоступны из-за области видимости. Давайте посмотрим на этот код в 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"
он работает даже тогда, когда оба,метод "multiply" и переменная "x", больше не существуют. А все потому, что закрытие возможности запомнить.