我最近从C / C ++迁移到了Python。难以理解闭包和装饰。
声明这些功能(在线博客以此片段代码为例)
def outer(some_func):
def inner():
print "Before Foo"
ret = some_func()
return ret + 1
return inner
def foo():
return 1
当我运行以下代码时
foo = outer(foo)
foo()
我得到了预期的输出
Before Foo
2
但是,如果我不止一次地运行它,我会得到奇怪的输出。我不明白会发生什么。
# Writing it down twice instead of running the same cell
# twice on my IPython notebook to better explain things here
foo = outer(foo)
foo = outer(foo)
foo()
输出如下
Before Foo
Before Foo
3
为什么我得到3作为输出,为什么"在Foo"之前打印两次?
编辑: - 当我再次装饰这个功能时会发生什么?现在运行foo = outer(foo)非常清楚。当我再次运行foo = outer(foo)时会发生什么?
答案 0 :(得分:1)
考虑<table id="datatable-buttons" class="table table-striped table-bordered">
<thead
<tr>
<th>Date</th>
<th>Amt</th>
<th>Status</th>
</tr>
</thead>
</table>
$(document).ready(function() {
//$('#datatable-buttons').DataTable( {
var table = $('#datatable-ajax').DataTable( {
"ajax": {
"url": "scripts/json.php",
"dataSrc": ""
},
"columns": [
{ "data": "date" },
{ "data": "amt" },
{ "data": "status" },
]
} );
的每个语句中foo
引用的内容。最初你将foo定义为一个总是返回1的函数。虽然你调用了foo=outer(foo)
,它现在有了一个新值。试着想象一下,在你运行那条线之前用foo相等的方法替换赋值右侧的foo。请记住,你在这里嵌套功能。
有几种方法可以帮助你了解正在发生的事情
答案 1 :(得分:1)
您再次装饰装饰功能。 outer
接受一个函数并返回闭包,当然它本身就是函数。没有什么能阻止您将返回的函数作为参数传递给以下调用,就像您在示例中所做的那样。
如果您更改代码以打印正在调用的函数并返回值,则更容易理解正在进行的操作:
def outer(some_func):
def inner():
print "Before inner, func: {0}".format(some_func)
ret = some_func()
print "After inner, return: {0}".format(ret + 1)
return ret + 1
return inner
def foo():
return 1
foo = outer(foo)
foo = outer(foo)
foo()
输出:
Before inner, func: <function inner at 0x7f1924b516e0>
Before inner, func: <function foo at 0x7f1924b51668>
After inner, return: 2
After inner, return: 3
答案 2 :(得分:0)
问题hoebenkr,我不明白当你将变量ret分配给函数的参数时,你调用函数。这是将变量声明为函数的事实上的标准吗?它迅速在python中运行?