请参阅下面的示例,使用 python 3.7,我找不到正确注释的方法。注释错误显示在注释中,由 mypy 给出。
正确注释的方法是什么?
非常感谢。
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()
我有一个实现“通用成员”的“通用类”
然后将其标记为:
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)
如何避免出现以下错误?
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
如果您不想允许在提供者构造函数中传递位置参数)。