简体   繁体   English

Function 闭包及含义<locals> object 中的语法 Python 中的名称</locals>

[英]Function closures and meaning of <locals> syntax in object name in Python

Suppose I have the following code:假设我有以下代码:

def outer(information):
    print(locals())
    def inner():
        print("The information given to me is: ", information)
    return inner


func1 = outer("info1")
print(func1)

It returns:它返回:

{'information': 'info1'}
<function outer.<locals>.inner at 0x1004d9d30>

Of course, if I call func1 , it will print with info1 in the statement.当然,如果我调用func1 ,它将在语句中打印 info1 。 So, from printing the locals() in the outer function, I can see that there is some relationship between the local scope and the storage of the argument.因此,通过在外部 function 中打印 locals(),我可以看到本地 scope 与参数的存储之间存在某种关系。

I was expecting func1 to simply be outer.inner , why does the syntax instead say outer.<locals>.inner ?我原以为 func1 只是outer.inner ,为什么语法改为outer.<locals>.inner Is this a syntactical way of clarifying that there are different local scopes associated to each of these functions - imagine I made another one func2 = outer("info2") - I return using the outer function?这是一种语法方式来阐明与这些函数中的每一个相关联的不同本地范围 - 想象我制作了另一个func2 = outer("info2") - 我使用外部 function 返回?

Also, is there something special about the enclosing <> syntax when used around a name?另外,在名称周围使用封闭的 <> 语法有什么特别之处吗? I see it around both the object and locals.我在 object 和当地人周围都看到了它。

See PEP 3155 -- Qualified name for classes and functions and the example with nested functions .请参阅PEP 3155 - 类和函数的限定名称以及嵌套函数的示例

For nested classes, methods, and nested functions, the __qualname__ attribute contains a dotted path leading to the object from the module top-level.对于嵌套类、方法和嵌套函数, __qualname__属性包含从模块顶层指向 object 的虚线路径。 A function's local namespace is represented in that dotted path by a component named <locals> .一个函数的本地命名空间在那个虚线路径中由一个名为<locals>的组件表示。

Since the __repr__ of a function uses the __qualname__ attribute, you see this extra component in the output when printing a nested function.由于__repr__的 __repr__ 使用__qualname__属性,因此在打印嵌套的 ZC1C425268E68385D1AB5074C17A94F1 时,您会在 output 中看到这个额外的组件。

I was expecting func1 to simply be outer.inner我期待 func1 只是outer.inner

That's not a fully qualified name.这不是一个完全限定的名称。 With this repr you might mistakenly assume you could import the name outer and dynamically access the attribute inner .使用此 repr,您可能会错误地认为您可以导入名称outer并动态访问属性inner Remember the qualname is a "dotted path leading to the object", but in this case attribute access is not possible because inner is a local variable.记住 qualname 是“指向对象的虚线路径”,但在这种情况下,属性访问是不可能的,因为inner是一个局部变量。

Also, is there something special about the enclosing <> syntax when used around a name?另外,在名称周围使用封闭的 <> 语法有什么特别之处吗?

There is nothing special about it, but it gives a pretty strong hint to the programmer that you can't access this namespace directly, because the name is not a valid identifier .它没有什么特别之处,但是它给程序员一个非常强烈的提示,你不能直接访问这个命名空间,因为这个名字不是一个有效的标识符

You can think of outer.<locals>.inner as saying that inner is a local variable created by the function.你可以认为outer.<locals>.inner是说inner 是一个由function 创建的局部变量。 inner is what is referred to a closure in computer science. inner是计算机科学中的闭包。 Roughly speaking a closure is like a lambda in that it acts as a function, but it requires non-global data be bundled with it to operate.粗略地说,闭包类似于 lambda,因为它充当 function,但它需要捆绑非全局数据才能运行。 In memory it acts as a tuple between information and a reference to the function being called.在 memory 中,它充当信息和对被调用的 function 的引用之间的元组。

foo = outer("foo")
bar = outer("bar")

# In memory these more or less looks like the following:
("foo", outer.inner)
("bar", outer.inner)

# And since it was created from a local namespace and can not be accessed
# from a static context local variables bundled with the function, it
# represents that by adding <local> when printed.

# While something like this looks a whole lot more convenient, it gets way
# more annoying to work with when the local variables used are the length of
# your entire terminal screen.
<function outer."foo".inner at 0x1004d9d30>

There is nothing inherently special about the <> other than informing you that <local> has some special meaning. <> 除了告诉你<local>有一些特殊的含义之外,它本身并没有什么特别之处。


Edit:编辑:

I was not completely sure when writing my answer, but after seeing @wim's answer <local> not only applies to closures created consuming variables within a local context.我在写我的答案时并不完全确定,但在看到@wim 的答案后<local>不仅适用于在本地上下文中创建的消耗变量的闭包。 It can be applied more broadly to all functions (or anything else) created within a local namespace.它可以更广泛地应用于在本地命名空间中创建的所有函数(或其他任何东西)。 So in summary foo.<local>.bar just means that "bar was created within the local namespace of foo".所以总而言之foo.<local>.bar只是意味着“bar 是在 foo 的本地命名空间中创建的”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM