函数机制是 Python 虚拟机的核心组成部分, 作用域 、名字空间 、闭包 、装饰器 等基本概念均与函数机制紧密联系。
正因如此,函数机制也成为 Python 工程师技术面重点讨论的内容。面试不仅考察后续人对相关知识点的理解,而且可通过类似 装饰器设计 这样的编码环节,考察候选人的程序设计能力。
真题讲解
❓Python 中有几个名字空间,分别是什么?Python 变量以什么顺序进行查找?
Python 总共有 4 个名字空间:
- 局部名字空间 ( locals )
- 闭包名字空间 ( closures )
- 全局名字空间 ( globals )
- 内建名字空间 ( builtin )
Python 查找变量时,依次检查 局部 、 闭包 、 全局 、 内建 这几个名字空间,直到变量被找到为止。更多详情,请参考虚拟机部分 作用域 与 名字空间 以及函数机制部分 函数调用 相关章节。
❓如何在一个函数内部修改全局变量?
在函数内部用 global 关键字将变量声明为全局,然后再进行修改:
|
|
❓不使用 def 关键字的话,还有什么办法可以创建函数对象?
根据 Python 对象模型,实例对象可以通过调用类型对象来创建。而函数类型对象,理论上可以通过函数对象找到:
|
|
实际上,Python 将函数类型对象暴露在 types 模块中,可通过模块属性 FunctionType 访问到:
|
|
函数对象包含以下要素,只要将这些要素备齐,即可调用函数类型对象创建新函数:
- code ,代码对象;
- globals ,全局名字空间;
- name ,函数名;
- argdefs ,默认参数值;
- closure ,闭包变量;
我们定义一个函数用于试验,它设置全局变量 value :
|
|
一开始全局名字空间并没有变量 value ,经过 set_global_value 函数设置后便可找到:
|
|
接下来,我们借助函数类型对象,创建一个与 set_global_value 类似的新函数 sgv ,只不过全局名字空间与我们指定的字典对象 g 绑定:
|
|
这样一来,调用 sgv 函数设置的全局变量,将保存在指定的全局名字空间,即字典 g 中:
|
|
这个例子纯粹为了演示如何通过函数类型对象创建新函数,虽不具备实际项目用途,但对理解函数运行机制很有帮助。
更多面试真题
❓请介绍装饰器的运行原理,并说说你对 @xxxx 这种写法的理解?
❓请设计一个装饰器,在函数执行时间超过指定值时输出日志
❓Python中的闭包变量可以被内部函数修改吗?
❓请描述执行以下程序将输出什么内容?并试着解释其中的原因。
上述的问题,你是否都能对答如流呢?点击 阅读原文,获取详细题解!
【Python源码剖析】系列文章首发于公众号【小菜学编程】,敬请关注:
【Python源码剖析】系列文章首发于公众号【小菜学编程】,敬请关注: