我可以为一个预定义的类型定义一个函数签名(包括参数和返回类型)。
假设有这样一个类型:
但是这种语法是不可行的。类型分配的正确语法是什么?
我可以这样做:
假设有这样一个类型:
safeSyntaxReadType = Callable[[tk.Tk, Notebook, str], Optional[dict]]
这意味着 safeSyntaxReadType
是一个接收 3 个参数(如上所列类型)的函数,它可以返回一个字典,也可能不返回任何东西。
现在假设我使用了一个名为safeReadJsonFile
的函数,其签名为:
def safeReadJsonFile(root = None, notebook = None, path = ''):
我想在函数签名中为函数 safeReadJsonFile
分配类型safeSyntaxReadType
,可能类似于:
def safeReadJsonFile:safeSyntaxReadType(root = None, notebook = None, path = ''):
但是这种语法是不可行的。类型分配的正确语法是什么?
我可以这样做:
def safeReadJsonFile(root:tk.Tk = None, notebook:Notebook = None, path:str = '') -> Optional[dict]:
但我希望避免这种情况。
阅读了很多(所有的类型文档,以及一些PEP544),我发现没有这样的语法能够在定义时轻松地为整个函数分配一个类型(最接近的是@typing.overload
,但并不完全符合我们的需求)。
但作为可能的解决方法,我实现了一个装饰函数,可以帮助轻松地分配类型:
def func_type(function_type):
def decorator(function):
def typed_function(*args, **kwargs):
return function(*args, **kwargs)
typed_function: function_type # type assign
return typed_function
return decorator
使用方法如下:
greet_person_type = Callable[[str, int], str]
def greet_person(name, age):
return "Hello, " + name + " !\nYou're " + str(age) + " years old!"
greet_person = func_type(greet_person_type)(greet_person)
greet_person(10, 10) # WHALA! typeerror as expected in `name`: Expected type 'str', got 'int' instead
现在我需要帮助:由于某些原因,类型检查器(PyCharm)不会为使用装饰语法的代码提供类型提示,尽管这种语法本应该是等价的:
@func_type(greet_person_type)
def greet_person(name, age):
return "Hello, " + name + " !\nYou're " + str(age) + " years old!"
greet_person(10, 10) # no type error. why?
我认为装饰器无法正常工作是因为装饰并没有改变原始的greet_person
函数,所以从返回的装饰函数中得到的类型信息对于使用原始的greet_person
函数时并没有影响。
我该如何使装饰器方法正常工作呢?
Callable
中使用它,则会返回Any...所以Optional[dict]
可能是正确的语法。 - Eliav Louski