Python 继承类型和成员重载的类型注释问题
Python type annotation issues with inheriting types and members overload
请看下面的例子,python 3.7,我找不到正确注释的方法。注释错误显示在注释中,由mypy给出。
- 我有一个 "generic class" 实现了 "generic members"。具体 类 和继承该结构的成员。
- 具体成员可以有额外的方法并为构造函数使用不同的参数。
正确注释的方法是什么?
非常感谢。
import abc
import typing
class ParentProvider(metaclass=abc.ABCMeta):
def __init__(self) -> None:
pass
class ChildProvider(ParentProvider):
def __init__(self, who: str) -> None:
ParentProvider.__init__(self)
self._who: str = who
@property
def p(self) -> str:
return "Hello %s" % self._who
class Parent(metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def providerType(self) -> typing.Type[ParentProvider]:
pass
@property
@abc.abstractmethod
def providerKwargs(self) -> typing.Dict[str, typing.Any]:
pass
@property
def provider(self) -> ParentProvider:
# How to avoid the following error?
# error: Too many arguments for "ParentProvider" [call-arg]
return self.providerType(**self.providerKwargs)
@abc.abstractmethod
def useIt(self) -> None:
pass
class Child(Parent):
@property
def providerType(self) -> typing.Type[ParentProvider]:
# Using Type[ChildProvider] instead Type[ParentProvider]
# doesn't helps
return ChildProvider
@property
def providerKwargs(self) -> typing.Dict[str, typing.Any]:
return dict(who='world')
def useIt(self) -> None:
# How to avoid the following error?
# error: "ParentProvider" has no attribute "p" [attr-defined]
print(self.provider.p)
if __name__ == "__main__":
Child().useIt()
I have a "generic class" which implements "generic members"
然后这样标记:
from typing import Generic, TypeVar
_T = TypeVar('_T', bound='ParentProvider')
class Parent(Generic[_T], metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def providerType(self) -> typing.Type[_T]:
pass
@property
@abc.abstractmethod
def providerKwargs(self) -> typing.Dict[str, typing.Any]:
pass
@property
def provider(self) -> _T:
return self.providerType(**self.providerKwargs)
@abc.abstractmethod
def useIt(self) -> None:
pass
现在具体的 Child
impl 变为:
class Child(Parent[ChildProvider]):
@property
def providerType(self) -> typing.Type[ChildProvider]:
return ChildProvider
@property
def providerKwargs(self) -> typing.Dict[str, typing.Any]:
return dict(who='world')
def useIt(self) -> None:
print(self.provider.p)
How to avoid the following error?
error: Too many arguments for "ParentProvider" [call-arg]
Parent.__init__
签名不允许传递任何参数 - 您可以使用
放宽它
class ParentProvider(metaclass=abc.ABCMeta):
def __init__(self, *args, **kwargs) -> None:
pass
(或者只是
class ParentProvider(metaclass=abc.ABCMeta):
def __init__(self, **kwargs) -> None:
pass
如果您不想允许在提供者构造函数中传递位置参数)。
请看下面的例子,python 3.7,我找不到正确注释的方法。注释错误显示在注释中,由mypy给出。
- 我有一个 "generic class" 实现了 "generic members"。具体 类 和继承该结构的成员。
- 具体成员可以有额外的方法并为构造函数使用不同的参数。
正确注释的方法是什么?
非常感谢。
import abc
import typing
class ParentProvider(metaclass=abc.ABCMeta):
def __init__(self) -> None:
pass
class ChildProvider(ParentProvider):
def __init__(self, who: str) -> None:
ParentProvider.__init__(self)
self._who: str = who
@property
def p(self) -> str:
return "Hello %s" % self._who
class Parent(metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def providerType(self) -> typing.Type[ParentProvider]:
pass
@property
@abc.abstractmethod
def providerKwargs(self) -> typing.Dict[str, typing.Any]:
pass
@property
def provider(self) -> ParentProvider:
# How to avoid the following error?
# error: Too many arguments for "ParentProvider" [call-arg]
return self.providerType(**self.providerKwargs)
@abc.abstractmethod
def useIt(self) -> None:
pass
class Child(Parent):
@property
def providerType(self) -> typing.Type[ParentProvider]:
# Using Type[ChildProvider] instead Type[ParentProvider]
# doesn't helps
return ChildProvider
@property
def providerKwargs(self) -> typing.Dict[str, typing.Any]:
return dict(who='world')
def useIt(self) -> None:
# How to avoid the following error?
# error: "ParentProvider" has no attribute "p" [attr-defined]
print(self.provider.p)
if __name__ == "__main__":
Child().useIt()
I have a "generic class" which implements "generic members"
然后这样标记:
from typing import Generic, TypeVar
_T = TypeVar('_T', bound='ParentProvider')
class Parent(Generic[_T], metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def providerType(self) -> typing.Type[_T]:
pass
@property
@abc.abstractmethod
def providerKwargs(self) -> typing.Dict[str, typing.Any]:
pass
@property
def provider(self) -> _T:
return self.providerType(**self.providerKwargs)
@abc.abstractmethod
def useIt(self) -> None:
pass
现在具体的 Child
impl 变为:
class Child(Parent[ChildProvider]):
@property
def providerType(self) -> typing.Type[ChildProvider]:
return ChildProvider
@property
def providerKwargs(self) -> typing.Dict[str, typing.Any]:
return dict(who='world')
def useIt(self) -> None:
print(self.provider.p)
How to avoid the following error?
error: Too many arguments for "ParentProvider" [call-arg]
Parent.__init__
签名不允许传递任何参数 - 您可以使用
class ParentProvider(metaclass=abc.ABCMeta):
def __init__(self, *args, **kwargs) -> None:
pass
(或者只是
class ParentProvider(metaclass=abc.ABCMeta):
def __init__(self, **kwargs) -> None:
pass
如果您不想允许在提供者构造函数中传递位置参数)。