Python 函数和模块的特殊属性__annotations__
众所周知,Python是一种动态类型语言,也是强类型语言。在Python语言中,使用变量之前不需要声明其类型,直接赋值即可创建变量,变量初始类型取决于等号右侧表达式的值的类型。创建之后,变量的类型可以随时发生变化,但在任何时刻,每个变量都有确定的类型。
同理,在定义函数和类的方法时,也不需要声明形参类型,完全取决于实参类型。例如,
很多从其他语言转过来的朋友很不习惯这样的方式,还是习惯于声明变量和参数的类型。虽然Python不支持声明,但是允许在定义函数时使用“注解”的形式来标注形参和返回值的类型,但这种注解的形式并不会对形参进行任何约束和检查,在实际调用函数时,即使实参不符合形参的类型标注,一样能够正常传递,这一点在《Python程序设计开发宝典》(董付国著,清华大学出版社)第126页有介绍。例如,
在Python中,函数会维护一个特殊属性__annotations__,这是一个字典,其中的“键”是被注解的形参名,“值”为注解的内容。使用时并不要求注解的内容是Python中的类型,可以是任意内容。例如,
Python函数有若干特殊属性,常用的几个如下图箭头所示,倒数第二个为__annotations__,
从官方文档来看,函数的__annotations__属性只包含形参和返回值的注解,即使在函数体中有类似的注解,但这并不等价于C语言中的变量声明,这样的注解不会创建变量,也不会被收集到这个特殊属性__annotations__中。例如,
另外,在模块中也有个特殊属性__annotations__用于收集模块中变量的注解,但这些注解同样也不会创建对应的变量。例如,在下面的代码中,并没有创建变量e、f、g。
Python官方文档对于模块特殊属性__annotations__的解释如下:
启动IDLE时,默认进入交互模式,是一个叫做__main__的命名空间,官方文档解释如下:
这样的话,在交互模式中也是可以访问特殊属性__annotations__的。例如,
以上分析源自于中国传媒大学胡凤国老师的一位学生提交的作业,代码如下,这应该是在交互模式下执行代码后复制到程序文件中删除前导提示符“>>> ”之后得到的,但这个程序却能够正确运行(注意:其中的冒号是英文半角符号)。有了上面的分析,这个程序能够正常运行也就容易理解了。感谢胡老师提供这样一个有意思的话题,感谢汪依妮同学无意中发现这样一个有意思的现象,感谢武汉理工大学赵广辉老师在群里积极交流并提出很好的思路。
原文链接:https://blog.csdn.net/dongfuguo/article/details/105103472