Python函数定义注解语法解析及类型提示与函数注解区别咨询
函数注解与类型提示的区别
- 函数注解(PEP3107):是Python 3.0引入的语法机制,允许给函数的参数、返回值附加任意表达式作为注解。它只是提供了一个语法容器,没有规定注解的具体用途——你可以用字符串写说明、用数字标记参数权重,甚至放任意合法的Python表达式。
示例:def calculate(a: "输入数值", b: 3.14) -> "计算结果": return a * b - 类型提示:是函数注解的一种特定用途,由PEP484正式规范,专门用注解来标注参数和返回值的类型,用于静态类型检查、IDE代码提示等。简单说,类型提示是把函数注解的位置用来放类型信息。
示例:def calculate(a: float, b: float) -> float: return a * b
总结:函数注解是语法基础,类型提示是这个语法的一个标准化应用场景。
PEP3107函数定义语法拆解(BNF规则通俗解释)
先明确BNF符号含义:[]表示可选内容,+表示至少出现一次,|表示二选一,*表示零次或多次。
decorator(单个装饰器)
decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE就是日常写的装饰器:
@后面跟一个可带点的名称(比如@staticmethod或@my_utils.log),可以选择加括号传参(@timer(interval=1))或不带(@timer),最后换行。decorators(多个装饰器)
decorators: decorator+允许叠加多个装饰器,至少一个,比如:
@dec1 @dec2(foo="bar") def func(): ...funcdef(完整函数定义)
funcdef: [decorators] 'def' NAME parameters ['->' test] ':' suite这是带注解的函数核心结构:
- 可选的装饰器列表
- 关键字
def+函数名 - 括号包裹的参数列表
- 可选的
->+返回值注解(test代表任意合法Python表达式) - 冒号+函数体(
suite就是缩进的代码块)
示例:def add(a: int, b: int) -> int: return a + b
parameters(参数列表容器)
parameters: '(' [typedargslist] ')'就是写函数时的
(),里面可以是空(def func():),也可以是带注解的参数列表typedargslist。typedargslist(带注解的参数集合)
这部分是参数规则的核心,分两种情况:typedargslist: ((tfpdef ['=' test] ',')* ('*' [tname] (',' tname ['=' test])* [',' '**' tname] | '**' tname) | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])通俗说:
- 第一种情况:先写零个或多个带默认值的普通参数,然后可以写
*args(可选加注解),后面跟零个或多个带默认值的关键字-only参数,最后可选加**kwargs;或者直接写**kwargs。
示例:def func(a: int = 0, *, b: str, **kwargs: dict): ... - 第二种情况:只写零个或多个带默认值的普通参数,最后可以加个尾逗号(比如
def func(a: int, b: str,): ...,Python允许这种写法)。
- 第一种情况:先写零个或多个带默认值的普通参数,然后可以写
tname(带注解的单个参数名)
tname: NAME [':' test]就是参数名加可选注解:比如
a(无注解)或a: int(带类型注解),test可以是任意表达式。tfpdef(带注解的参数定义)
tfpdef: tname | '(' tfplist ')'可以是单个带注解的参数名,也可以是元组形式的参数(注:这种元组参数注解在Python 3后续版本中已被废弃,比如
def func((x, y): tuple): ...现在不推荐使用)。tfplist(元组参数列表)
tfplist: tfpdef (',' tfpdef)* [',']元组参数里的多个参数项,用逗号分隔,最后可选加尾逗号,比如
(x: int, y: str,)。
内容的提问来源于stack exchange,提问作者Ryu10
相关产品推荐
相关产品推荐

