继承类型和成员重载的Python类型注释问题
请参阅下面的例子,使用Python3.7,我无法找到正确注释的方法。注释错误显示在注释中,由mypy给出继承类型和成员重载的Python类型注释问题,python,python-3.x,mypy,type-annotation,Python,Python 3.x,Mypy,Type Annotation,请参阅下面的例子,使用Python3.7,我无法找到正确注释的方法。注释错误显示在注释中,由mypy给出 我有一个实现“泛型成员”的“泛型类”。以及继承该结构的具体类和成员 具体成员可以有其他方法,并为构造函数使用不同的参数 怎样才能正确地诠释这一点 非常感谢 import abc import typing class ParentProvider(metaclass=abc.ABCMeta): def __init__(self) -> None: pa
- 我有一个实现“泛型成员”的“泛型类”。以及继承该结构的具体类和成员
- 具体成员可以有其他方法,并为构造函数使用不同的参数
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
现在,特定的子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.\uuuu init\uuuu
签名不允许传递任何参数-您可以使用
class ParentProvider(metaclass=abc.ABCMeta):
def __init__(self, *args, **kwargs) -> None:
pass
(或只是
如果不希望允许在提供程序(构造函数)中传递位置参数
我有一个实现“泛型成员”的“泛型类”
然后将其标记为:
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
现在,特定的子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.\uuuu init\uuuu
签名不允许传递任何参数-您可以使用
class ParentProvider(metaclass=abc.ABCMeta):
def __init__(self, *args, **kwargs) -> None:
pass
(或只是
如果不想允许在提供程序构造函数中传递位置参数)。对于“Child.useIt”方法,在使用self.provider.p之前,解决方法是“assert-isinstance(self.provider,self.providerType)”。但这在Parent.provider中不起作用,因为它还不知道最终的providerType类型。您将关键字参数传递给providerType
,但未将其定义为接受任何参数providerKwargs
是一种方法,但您并没有调用它(您将其视为dict
本身)。谢谢@chepner。父级在Parent.provider属性中安装提供程序时会使用providerKwargs。谁使用它并不重要,因为您使用不正确。如果它是一个方法,则必须调用它:返回self.providerType(**self.providerKwargs())
。您仍然需要更改providerType
的签名以接受关键字参数。@chepner providerKwargs是一个属性…对于“Child.useIt”方法,在使用self.provider.p之前,解决方法是“assert-isinstance(self.provider,self.providerType)”。但这在Parent.provider中不起作用,因为它还不知道最终的providerType类型。您将关键字参数传递给providerType
,但未将其定义为接受任何参数providerKwargs
是一种方法,但您并没有调用它(您将其视为dict
本身)。谢谢@chepner。父级在Parent.provider属性中安装提供程序时会使用providerKwargs。谁使用它并不重要,因为您使用不正确。如果它是一个方法,则必须调用它:返回self.providerType(**self.providerKwargs())
。您仍然需要更改providerType
的签名以接受关键字参数。@chepner providerKwargs是一个属性…很乐意帮助!:-)很乐意帮忙!:-)