玩过 turtle 库的应该知道,turtle也是可以监控鼠标和键盘事件的。没玩过的下面也能看懂。
下面这段程序可以实现按键 a 键打印字符 'A'。
'''按下按键 a,打印字母 A'''
import turtle
screen = turtle.Screen()
def display():
print('A')
turtle.onkey(display,'a')
screen.listen()
turtle.done()
其中第8行代码的display是回调函数(触发事件才会调用),不能有括号,当按下a 键后,该方法才会被执行。如果加上括号呢,那么该程序启动后没有按按键就会执行。
上面的代码很好理解。
下面我有一个新的需求,实现按下任意字母按键,打印对应按键内容。比如按下b打印字符'b',按下c打印字符'c'。
到这里大家很容易会想到给display方法传递一个参数。
def display(key):
print(key)
然后创建一个包含26个字母的字符串变量,最后循环遍历这个字符串监控所有按键。
letters = 'abcdefghijklmnopqrstuvwxyz'
for key in letters:
turtle.onkey(display(key),key)
但是这样就有问题了,因为函数display(key)没有按下按键就直接被调用了,运行程序就会打印一串a-z的字符。
a
b
...
y
z
既然只能使用回调函数,我们可不可以让我们的函数返回一个函数呢?
更改之前的函数。
def display2(key):
def display():
print(key)
return display # 返回函数非常关键
由于display2返回的就是一个函数,现在onkey方法就可以传入key参数调用display2(key)了。
def display2(key):
def display():
print(key)
return display # 返回函数非常关键
letters = 'abcdefghijklmnopqrstuvwxyz'
for key in letters:
turtle.onkey(display2(key), key)
上面的display函数其实就是一个闭包。
函数可以作为返回值,也可以内部定义。这种在函数里传递、嵌套、返回其他函数的情况,称之为高阶函数。除此之外,函数还可以作为其它函数的参数。高阶函数中,内层函数携带外层函数中的参数、变量及其环境,一同存在的状态(即使已经离开了创造它的外层函数)被称之为闭包。
当然了,如果你学过lambda方法,使用匿名函数也可以搞定,不过不熟悉可能不好理解,本质上和前面的原理是一样的。
def display(key):
print(key)
letters = 'abcdefghijklmnopqrstuvwxyz'
for key in letters:
turtle.onkey((lambda key=key:display(key)),key)
screen.listen()
在装饰器中,闭包应用的非常多,感兴趣的可以去了解一下。
很多时候,可能你并不知道闭包或者某个技术名词的概念,仅仅是根据问题你想出了前面的解决方法,而后听别人说才知道自己用的是闭包,是不是有一种创造的感觉呢?
问题 → 产生需求 → 技术,循环往复,新的问题或现象产生,之前的技术有缺陷 → 产生需求 → 新的技术;
学习知识的时候,构建出层层递进的需求,设计出层层递进的技术演变过程。你学习的时候会很惊讶,为何如此巧妙。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有