Python: python ast 中的 ast.FunctionType 是什么?
Python: what is the ast.FunctionType in python ast?
我不假装理解了 python ast 中的所有内容,但是 FunctionType 是困扰我的东西。
mod = Module(stmt* body, type_ignore *type_ignores)
| Interactive(stmt* body)
| Expression(expr body)
| FunctionType(expr* argtypes, expr returns)
| Suite(stmt* body)
它可以是什么?
FunctionType
是顶级符号 returned 用于解析函数类型的 # type: (args) -> return_type
注释(由 PEP484 指定)
我能找到的唯一权威来源是 Python 3.8 的更新日志,其中添加了它:https://docs.python.org/3/whatsnew/3.8.html#ast
您可以使用 compile
或 ast.parse
和 'func_type'
模式解析此类内容(其中模式通常是 exec
语句和 eval
用于表达式)。
这仅在您尝试使用 Python 2 语法注释函数 return 类型时(由外部类型检查软件使用)使用,例如:
# Invalid syntax in Python 2
# def f(x: int, y: int) -> int:
# return x * y
# Special type of type hint for functions in Python 2 (and also works in Python 3)
def f(x, y):
# type: (int, int) -> int
return x * y
# Or alternative syntax:
def f(
x, # type: int
y # type: int
):
# type: (...) -> int
return x * y
普通类型注解只能在'eval'
模式下解析,但函数类型注解不能,所以添加了新模式和顶级符号:
https://github.com/python/cpython/blob/main/Grammar/python.gram#L91
func_type[mod_ty]: '(' a=[type_expressions] ')' '->' b=expression NEWLINE* ENDMARKER { _PyAST_FunctionType(a, b, p->arena) }
类型检查器可以使用它来解析这些类型的注释:
import ast
source = '''
def f(x, y):
# type: (int, int) -> int
return x * y
'''
module = ast.parse(source, mode='exec', type_comments=True)
class PrintFunctionTypes(ast.NodeVisitor):
def visit_FunctionDef(self, f):
print('FunctionDef:\n' + ast.dump(f))
print('\ntype_comment:\n' + f.type_comment)
parsed_comment = ast.parse(f.type_comment, mode='func_type')
print('\nWhen parsed:\n' + ast.dump(parsed_comment))
PrintFunctionTypes().visit(module)
输出:
FunctionDef:
FunctionDef(name='f', args=arguments(posonlyargs=[], args=[arg(arg='x'), arg(arg='y')], kwonlyargs=[], kw_defaults=[], defaults=[]), body=[Return(value=BinOp(left=Name(id='x', ctx=Load()), op=Mult(), right=Name(id='y', ctx=Load())))], decorator_list=[], type_comment='(int, int) -> int')
type_comment:
(int, int) -> int
When parsed:
FunctionType(argtypes=[Name(id='int', ctx=Load()), Name(id='int', ctx=Load())], returns=Name(id='int', ctx=Load()))
我不假装理解了 python ast 中的所有内容,但是 FunctionType 是困扰我的东西。
mod = Module(stmt* body, type_ignore *type_ignores)
| Interactive(stmt* body)
| Expression(expr body)
| FunctionType(expr* argtypes, expr returns)
| Suite(stmt* body)
它可以是什么?
FunctionType
是顶级符号 returned 用于解析函数类型的 # type: (args) -> return_type
注释(由 PEP484 指定)
我能找到的唯一权威来源是 Python 3.8 的更新日志,其中添加了它:https://docs.python.org/3/whatsnew/3.8.html#ast
您可以使用 compile
或 ast.parse
和 'func_type'
模式解析此类内容(其中模式通常是 exec
语句和 eval
用于表达式)。
这仅在您尝试使用 Python 2 语法注释函数 return 类型时(由外部类型检查软件使用)使用,例如:
# Invalid syntax in Python 2
# def f(x: int, y: int) -> int:
# return x * y
# Special type of type hint for functions in Python 2 (and also works in Python 3)
def f(x, y):
# type: (int, int) -> int
return x * y
# Or alternative syntax:
def f(
x, # type: int
y # type: int
):
# type: (...) -> int
return x * y
普通类型注解只能在'eval'
模式下解析,但函数类型注解不能,所以添加了新模式和顶级符号:
https://github.com/python/cpython/blob/main/Grammar/python.gram#L91
func_type[mod_ty]: '(' a=[type_expressions] ')' '->' b=expression NEWLINE* ENDMARKER { _PyAST_FunctionType(a, b, p->arena) }
类型检查器可以使用它来解析这些类型的注释:
import ast
source = '''
def f(x, y):
# type: (int, int) -> int
return x * y
'''
module = ast.parse(source, mode='exec', type_comments=True)
class PrintFunctionTypes(ast.NodeVisitor):
def visit_FunctionDef(self, f):
print('FunctionDef:\n' + ast.dump(f))
print('\ntype_comment:\n' + f.type_comment)
parsed_comment = ast.parse(f.type_comment, mode='func_type')
print('\nWhen parsed:\n' + ast.dump(parsed_comment))
PrintFunctionTypes().visit(module)
输出:
FunctionDef:
FunctionDef(name='f', args=arguments(posonlyargs=[], args=[arg(arg='x'), arg(arg='y')], kwonlyargs=[], kw_defaults=[], defaults=[]), body=[Return(value=BinOp(left=Name(id='x', ctx=Load()), op=Mult(), right=Name(id='y', ctx=Load())))], decorator_list=[], type_comment='(int, int) -> int')
type_comment:
(int, int) -> int
When parsed:
FunctionType(argtypes=[Name(id='int', ctx=Load()), Name(id='int', ctx=Load())], returns=Name(id='int', ctx=Load()))