首页 > 其他 > 详细

第020讲:函数:内嵌函数和闭包

时间:2021-06-07 23:03:08      阅读:29      评论:0      收藏:0      [点我收藏+]

第020讲:函数:内嵌函数和闭包


测试题

0. 如果希望在函数中修改全局变量的值,应该使用什么关键字?

  • global 关键字可以击穿函数,达到修改全局变量的目的

1. 在嵌套的函数中,如果希望在内部函数修改外部函数的局部变量,应该使用什么关键字?

  • nonlocal 关键字用于函数中嵌套函数调用上层函数的局部变量

2. Python 的函数可以嵌套,但要注意访问的作用域问题哦,请问以下代码存在什么问题呢?

def outside():
    print(‘I am outside!‘)
    def inside():
        print(‘I am inside!‘)

inside()
  • 这段代码调用的 inside 函数是 outside函数内部的嵌套函数,不能在outside函数外部调用,超出了inside 的作用域,正确的调用应该是:
def outside():
    print(‘I am outside!‘)
    def inside():
        print(‘I am inside!‘)
    return inside()
outside()

3. 请问为什么代码 A 没有报错,但代码 B 却报错了?应该如何修改?

  • 代码A
def outside():
    var = 5
    def inside():
        var = 3
        print(var)
        
    inside()
outside()
  • 代码B
def outside():
    var = 5
    def inside():
        print(var)
        var = 3
        
    inside()
outside()
  • 问题在于inside是outside的嵌套函数,outside函数中第一行代码是打印var变量,第二行才是ver变量赋值,但是在python中,嵌套函数不能直接调用上层函数,再一个根据python属于解释型语言,代码运行方式是逐行运行,因此 print(ver) 中 ver 变量此刻实际上并没有定义

4. 请问如何访问 funIn() 呢?

def funOut():
    def funIn():
        print(‘宾果!你成功访问到我啦!‘)
    return funIn()
  • 这里只需要直接调用 funOut 函数即可

5. 请问如何访问 funIn() 呢?

def funOut():
    def funIn():
        print(‘宾果!你成功访问到我啦!‘)
    return funIn

‘‘‘这里的意思是,funOut 函数不加括号,表示返回它的内存地址
然而加一个括号的情况下,由于funOut函数返回的是内部函数funIn的值
而返回 return funIn 函数没有小括号,因此返回的也是它的内存地址,
所以最终 funOut 函数如果要调用funIn的返回值,需要再加一个小括号‘‘‘

6. 以下是“闭包”的一个例子,请你目测下会打印什么内容?

def funX():
    x = 5
    def funY():
        nonlocal x
        x += 1
        return x
    return funY

a = funX()
print(a())
print(a())
print(a())
  • 按理说每次调用 funX 函数的时候,内部的变量都会被初始化为 x = 5,但由于将函数 funX() 赋值给了变量 a ,那么只要a 这个变量的赋值没被更改或重新赋值,那么函数 funX() 其实就没有被释放,所以这里的答案是:
6
7
8

动动手

0. 请用已学过的知识编写程序,统计下边这个长字符串中各个字符出现的次数并找到小甲鱼送给大家的一句话。

a = ‘字符串‘
list1 = []
list2 = []
for i in a:
    if i not in list1:
        if i == ‘\n‘:
            print(‘换行‘, a.count(i))   # a.count(i) 方法可以直接统计在字符串a中,字符 i 出现的次数
        else:
            print(i, a.count(i))
        list1.append(i)
    if i.isalpha():     # 把字母和汉字提取并写入list2 列表
        list2.append(i)
        
print(‘‘.join(list2))   # 用join方法把list2 列表转字符串

1. 请用已学过的知识编写程序,找出小甲鱼藏在下边这个长字符串中的密码,密码的埋藏点符合以下规律:

  • 每位密码为单个小写字母
  • 每位密码的左右两边均有且只有三个大写字母
str1 = ‘字符串‘

countA = 0  # 统计前边的大写字母
countB = 0  # 统计小写字母
countC = 0  # 统计后边的大写字母
length = len(str1)

for i in range(length):
    if str1[i] == ‘\n‘:
        continue

    """
    |如果str1[i]是大写字母:
    |-- 如果已经出现小写字母:
    |-- -- 统计后边的大写字母
    |-- 如果未出现小写字母:
    |-- -- 清空后边大写字母的统计
    |-- -- 统计前边的大写字母
    """
    if str1[i].isupper():
        if countB:
            countC += 1
        else:
            countC = 0
            countA += 1

    """
    |如果str1[i]是小写字母:
    |-- 如果小写字母前边不是三个大写字母(不符合条件):
    |-- -- 清空所有记录,重新统计
    |-- 如果小写字母前边是三个大写字母(符合条件):
    |-- -- 如果已经存在小写字母:
    |-- -- -- 清空所有记录,重新统计(出现两个小写字母)
    |-- -- 如果该小写字母是唯一的:
    |-- -- -- countB记录出现小写字母,准备开始统计countC
    """
    if str1[i].islower():
        if countA != 3:
            countA = 0
            countB = 0
            countC = 0
        else:
            if countB:
                countA = 0
                countB = 0
                countC = 0
            else:
                countB = 1
                countC = 0
                target = i

    """
    |如果前边和后边都是三个大写字母:
    |-- 如果后边第四个字母也是大写字母(不符合条件):
    |-- -- 清空记录B和C,重新统计
    |-- 如果后边仅有三个大写字母(符合所有条件):
    |-- -- 打印结果,并清空所有记录,进入下一轮统计
    """
    if countA == 3 and countC == 3:
        if i+1 != length and str1[i+1].isupper():
            countB = 0
            countC = 0
        else:
            print(str1[target], end=‘‘)
            countA = 3
            countB = 0
            countC = 0

第020讲:函数:内嵌函数和闭包

原文:https://www.cnblogs.com/jaderadish/p/14860388.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!