[英]How do I type hint a function that returns an instance of the current class?
Let's say I have these classes:假设我有这些课程:
class GenericCopyable:
def copy(self) -> GenericCopyable:
... # whatever is required to copy this
class CopyableFoo(GenericCopyable):
... # uses the parent implementation of "copy"
def bar(self): …
def some_code(victim: CopyableFoo):
v = victim.copy()
v.bar() ### I know that this works because "v" is a CopyableFoo, but mypy doesn't
The problem is that I need the return type of CopyableFoo.copy()
to be CopyableFoo
, not GenericCopyable
.问题是我需要CopyableFoo.copy()
的返回类型是CopyableFoo
,而不是GenericCopyable
。
Is that possible?那可能吗?
Edited: The above is sample code to illustrate the problem.编辑:以上是说明问题的示例代码。 Modifying some_code
or CopyableFoo
in some way is certainly possible in this example;在这个例子中,以某种方式修改some_code
或CopyableFoo
肯定是可能的; in my "real" program that'd be substantially more difficult.在我的“真实”程序中,这会更加困难。
You could do this.你可以这样做。
from typing import TypeVar
# We define T as a TypeVar bound to the base class GenericCopyable
T = TypeVar('T', bound='GenericCopyable')
class GenericCopyable:
# we return the type T of the type of self
# Basically returning an instance of the calling
# type's class
def copy(self: T) -> T:
return type(self)()
class CopyableFoo(GenericCopyable):
pass
foo = CopyableFoo()
bar = foo.copy()
print(bar)
This looks a little clumsy because typically we don't need to annotate self
, since it's implicitly a type of the class it's bound to.这看起来有点笨拙,因为通常我们不需要注释self
,因为它隐式地是它绑定到的类的类型。 However, mypy seems to be ok with it.但是,mypy 似乎没问题。
One possible solution is to override the method in your children class and then call your superclass method with the children class method specifying the return type of their own instance.一种可能的解决方案是覆盖子类中的方法,然后使用子类方法调用超类方法,指定它们自己实例的返回类型。
class GenericCopyable:
def copy(self) -> GenericCopyable:
... # whatever is required to copy this
class CopyableFoo(GenericCopyable):
def copy(self)->CopyableFoo:
return super().copy()
Another possible solution is by using the typing module to import Union.另一种可能的解决方案是使用typing 模块导入Union。 This specifies the function in your parent class is able to return multiple types这指定您的父类中的函数能够返回多种类型
from typing import Union
class GenericCopyable:
def copy(self) -> Union[GenericCopyable,CopyableFoo]:
... # whatever is required to copy this
class CopyableFoo(GenericCopyable):
#Call parent class method directly
GenericCopyable.copy()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.