我正在编写一个Python包,该包使用装饰器删除样板代码,同时自省函数以获取默认的函数名称。类似于以下内容:
def make_real_instance(func: Optional[Callable] = None,
*, func_name: Optional[str] = None):
def make_wrapper(in_func):
@functools.wraps(in_func)
def wrapper(*args, **kwargs):
nonlocal func_name
# Use func_name if provided
func_name = func_name or in_func.__name__
# Construct params for new object from function and its inputs
stuff = in_func(*args, **kwargs)
# Process stuff commonly
new_object = ObjectConstructor(processed_stuff, func_name)
return new_object
return wrapper
if func:
return make_wrapper(func)
return make_wrapper
现在,我有这样的课程:
class ObjectConstructor:
def __init__(self, ...):
#do stuff
@make_real_instance
def add_foo(self, foo_length: float):
stuff = ... # process the input for this method
return stuff
@make_real_instance
装饰器使add_foo
实例的ObjectConstructor
方法的调用返回一个 new 实例。但是,未修饰方法的实际返回类型是元组。
我想做的是对方法进行注释,以提示提示返回作为ObjectConstructor
的实例。即一行:
def add_foo(self, foo_length: float):
将成为(已从annotations
导入__future__
):
def add_foo(self, foo_length: float): -> ObjectConstructor
但是,我的IDE(PyCharm,尽管在这种情况下我不一定认为它是实质性的)抱怨(我想很公平)此方法的输出与提示的返回类型不匹配。
最后,我的问题:有没有一种方法可以正确地键入提示以修改使用装饰器的输出的函数调用的返回类型?还是我唯一的方法是将装饰器更改为我在装饰的每个函数中调用的函数,并每次显式传递func_name
参数?我的意思是这样的:
def make_obj_from_stuff(stuff, func_name) -> ObjectConstructor:
# process stuff commonly
new_object = new_object = ObjectConstructor(processed_stuff, func_name)
return new_object
class ObjectConstructor:
def __init__(self, ...):
#do stuff
def add_foo(self, foo_length: float) -> ObjectConstructor:
stuff = ... # process the input
new_obj = make_obj_from_stuff(stuff, "add_foo")
return new_obj
如果我想维护自己创建的装饰器接口,是否只需要接受我不会抱怨我的IDE就不能正确键入提示?