python嵌套函数作用域怎么解释
阿神
阿神 2017-04-18 10:23:18
0
3
583

直接上代码

def l(list):
    def d():
        return list
    return d
    
 #运行
l = l([1,2,3,4])
print l()

这个情况是正常的。

问题在于d函数为什么不能传入list,然后我现在尝试了一下这个代码:

def l(list):
    def d(list):
        return list
    return d
 
#运行
l = l([1,2,3,4])
#提示错误
print l()

#正常
print l([1,3,5,7,9])

请问这个怎么解释呢?
我个人理解的是,类似于“继承”的情况,当d函数没有参数传入的情况上,基于父函数的参数,当他需要传参了,就覆盖了???

阿神
阿神

闭关修行中......

reply all(3)
洪涛

Look at the LEGB principles and you will understand what is going on.
https://zhuanlan.zhihu.com/p/...

Run

l = l([1,2,3,4])

Prompt error

print l() This error is that you did not pass parameters.

迷茫

In the original code:

def l(list):
    def d(list):
        return list
    return d  # <-- 这里是返回的一个要传入一个参数的函数
 
#运行
l = l([1,2,3,4])
#提示错误
print l() # <-- 这里没有传入参数报错,这里的 l 是 返回的闭包 d

#正常
print l([1,3,5,7,9]) # <-- 这里的 l 已经不是你最初定义的 l 而是 最初 l 中返回的 d

The following is for illustration: l in your original code points to a different point:

def l(list):
    def d(list):
        return list
    return d
 
#运行
print 'id(l) is {}'.format(id(l))
l = l([1,2,3,4])
#提示错误
# print l()

#正常
print 'id(l) is {}'.format(id(l))
print l([1,3,5,7,9])

You may understand if the code is written like this:

def l(_list):
    def d(_l):
        return _list + _l
    return d
 
a = l([1,2,3,4])
print a([1])

Two final points:

  1. Don’t use keywords like list as variable names

  2. Don’t overwrite your variable names (unless really necessary)

Ty80

What the poster needs to understand is: Scope

Case 1: Function l returns the address of function d, which is only used as a return value and has not been called for execution.

In [3]: print(l([1,2,3,4]))
<function l.<locals>.d at 0x7f49243ece18>

  The parameter list is passed to l, the scope is within the function l, and can be accessed by d (note that the parameter is passed to l, not d).
  
  If you want to access the list, call as follows:
  
  `

    In [2]: print(l([1,2,3,4])())
    [1, 2, 3, 4]
    
相当于:
    
    In [5]: d = l([1,2,3,4])    # 返回d的地址
    
    In [6]: d()          #调用d,d没有参数,不需要传参
    Out[6]: [1, 2, 3, 4]

case 2: 同样l返回d的地址,但此时返回的函数d需要传参(注意l的参数list和d的参数list是不一样的).
   
    In [8]: d = l([1,2,3,4])  # 返回函数d的地址,参数list此时并没有用到
    
    In [9]: d([5,6,7,8])    # 需要参数的函数d
    Out[9]: [5, 6, 7, 8]
    
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template