简体   繁体   English

如何键入提示返回当前类实例的函数?

[英]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_codeCopyableFoo肯定是可能的; 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM