Discuss / Python / 为了加强理解,做了一些类比试验

为了加强理解,做了一些类比试验

Topic source
def count():
    fs = []
    for i in range(1, 4):
        def f():
             return i*i
        fs.append(f())    # 列表中的元素为f()的返回值,即int型数据
    return fs    # 返回值为列表

a = count()
print(a)

def count1():
    # fs = []
    for i in range(1, 4):
        def f():
             return i*i
        # fs.append(f())
    return f    # 返回值为function类型,for循环里相互覆盖,因此只返回最后一次的函数对象

a = count1()
print(a)
print(a())

def count2():
    fs = []
    for i in range(1, 4):
        def f():
             return i*i    # 引用了外部变量i,但并非立即执行,直到调用f()时才执行,此时i的值已经都变了
        fs.append(f)    # 列表中的元素为function类型,返回for循环的三个元素
    return fs    # 返回值为列表

a = count2()
print(a)
for n in a:
    print(n())

def count3():
    def g(j):
        def f():
            return j * j    # 这里每次f()在调用时,其引用的外部变量j已经确定了
        return f
    fs = []

    for i in range(1, 4):
        fs.append(g(i))    # 列表中的元素为function类型,返回for循环的三个元素
    return fs    # 返回值为列表

a = count3()
print(a)
for n in a:
    print(n())

def createCounter():
    L = [0]    # 列表L的内存地址在初次调用时已经给定,且L[0]即第一个元素指向整数0
    def counter():
        L[0] += 1    # 改变列表L中第一个元素的值,但并没有改变列表L的内存地址
        return L[0]
    return counter

counterA = createCounter()
print(counterA(), counterA(), counterA(), counterA(), counterA()) # 1 2 3 4 5
counterB = createCounter()
if [counterB(), counterB(), counterB(), counterB()] == [1, 2, 3, 4]:
    print('测试通过!')
else:
    print('测试失败!')

谢岳松

#2 Created at ... [Delete] [Delete and Lock User]

膜拜

duck卢

#3 Created at ... [Delete] [Delete and Lock User]

看了楼主这个终于理解了

def createCounter(): n = 0 def counter(): nonlocal n n += 1 return n return counter

这段代码如果不加nonlocal,会报错,这是因为对于fun1函数,x是局部变量,对于fun2函数,n是非全局的外部变量。当在fun2中对n进行修改时,会将n视为fun2的局部变量,屏蔽掉fun1中对n的定义;如果仅仅在fun2中对n进行读取,则不会出现这个错误。

而写成列表则不会报错,reason楼主写的很清楚了

def createCounter(): L = [0] # 列表L的内存地址在初次调用时已经给定,且L[0]即第一个元素指向整数0 def counter(): L[0] += 1 # 改变列表L中第一个元素的值,但并没有改变列表L的内存地址 return L[0] return counter

谢谢解答


  • 1

Reply