如何在python中使用类型提示来执行一个方法完全返回其参数

时间:2016-08-31 00:10:58

标签: python-3.5 type-hinting

这是我的基本代码。

from typing import Optional


class State:
    name = 'unnamed state'

    def __init__(self, name: str = None) -> None:
        super().__init__()

        if name is not None:
            self.name = name

    def on_enter(self) -> None:
        pass

    def on_leave(self) -> None:
        pass

    def to(self, dest: Optional['State']) -> Optional['State']:
        self.on_leave()
        if dest is not None:
            dest.on_leave()
        return dest


class AState(State):
    pass


class BState(State):
    def b_func(self):
        pass


a = AState()
b = BState()

a.to(b).b_func()

当前的类型提示显示a.to(b)的类型为Optional[State],但我想要的是返回参数is self,即BState。这在Python的类型系统中是否可用?

1 个答案:

答案 0 :(得分:0)

If you'd like to have a function always return exactly the same type as its parameter, you can use generics via the TypeVars class:

from typing import Optional, TypeVar

# Note that "TState" is an arbitrary name.
TState = TypeVar('TState', bound='State')

class State:
    name = 'unnamed state'

    def __init__(self, name: str = None) -> None:
        super().__init__()

        if name is not None:
            self.name = name

    def on_enter(self) -> None:
        pass

    def on_leave(self) -> None:
        pass

    def to(self, dest: Optional[TState]) -> Optional[TState]:
        self.on_leave()
        if dest is not None:
            dest.on_leave()
        return dest


class AState(State):
    pass


class BState(State):
    def b_func(self):
        pass


a = AState()
b = BState()

a.to(b).b_func()

The expression TState = TypeVar('TState', bound=State) means "create a new generic parameter named TState which must always be a subclass of a State object." However, since the State class isn't defined yet, we need to use a forward reference and have the bound be a string instead of the class name: TState = TypeVar('TState', bound='State').

You could also do TState = TypeVar('TState') which means "create a new generic parameter named TState which can be anything", but that probably isn't what you want so I don't recommend it.

You can learn more about upper bounds in TypeVars here: http://mypy.readthedocs.io/en/latest/generics.html#type-variables-with-upper-bounds