Python 使用处理程序工厂时无法推断子类的静态类型
Python can't infer static type of subclass when using a handler factory
我想使用通用的 HandlerFactory
class,就像 here 中描述的那样(参见 解决方案 2:元编程)。
让我举个例子:
假设我们有以下 classes:
class Person:
name: str
@PersonHandlerFactory.register
class Mark(Person):
name = "Mark"
job = "scientist"
@PersonHandlerFactory.register
class Charles(Person):
name = "Charles"
hobby = "football"
您可能已经注意到子classes 包含一个装饰器。此装饰器用于将这些 classes 注册到以下 PersonHandlerFactory
class,其中 returns 一个特定的 class 给定的人名:
from typing import Dict, Type
class PersonHandlerFactory:
handlers: Dict[str, Type[Person]] = {}
@classmethod
def register(cls, handler_cls: Type[Person]):
cls.handlers[handler_cls.name] = handler_cls
return handler_cls
@classmethod
def get(cls, name: str):
return cls.handlers[name]
如您所见,我使用了 Type[Person]
类型,因为我希望此方法用于 Person
.
的任何子 class
但不知何故 Python 将任何子实例的静态类型class 解释为 class Parent
:
mark = Mark() # Static type of 'mark' is 'Person' :S
print(mark.job) # Python can't find the type of 'job'
我不想为 Mark | Charles
更改 Type[Person]
因为 class PersonHandlerFactory
不应该知道 [=] 的子 class 17=].
使用边界 TypeVar,这样可以推断出正确的子class。
from typing import Dict, Type, TypeVar
class Person:
name: str
T = TypeVar("T", bound=Person)
class PersonHandlerFactory:
handlers: Dict[str, Type[Person]] = {}
@classmethod
def register(cls, handler_cls: Type[T]) -> Type[T]:
cls.handlers[handler_cls.name] = handler_cls
return handler_cls
@classmethod
def get(cls, name: str):
return cls.handlers[name]
@PersonHandlerFactory.register
class Mark(Person):
name = "Mark"
job = "scientist"
mark = Mark() # Static type of 'mark' is 'Mark' :)
PersonHandlerFactory.get
返回的 class 将始终被推断为 Type[Person]
我想使用通用的 HandlerFactory
class,就像 here 中描述的那样(参见 解决方案 2:元编程)。
让我举个例子:
假设我们有以下 classes:
class Person:
name: str
@PersonHandlerFactory.register
class Mark(Person):
name = "Mark"
job = "scientist"
@PersonHandlerFactory.register
class Charles(Person):
name = "Charles"
hobby = "football"
您可能已经注意到子classes 包含一个装饰器。此装饰器用于将这些 classes 注册到以下 PersonHandlerFactory
class,其中 returns 一个特定的 class 给定的人名:
from typing import Dict, Type
class PersonHandlerFactory:
handlers: Dict[str, Type[Person]] = {}
@classmethod
def register(cls, handler_cls: Type[Person]):
cls.handlers[handler_cls.name] = handler_cls
return handler_cls
@classmethod
def get(cls, name: str):
return cls.handlers[name]
如您所见,我使用了 Type[Person]
类型,因为我希望此方法用于 Person
.
但不知何故 Python 将任何子实例的静态类型class 解释为 class Parent
:
mark = Mark() # Static type of 'mark' is 'Person' :S
print(mark.job) # Python can't find the type of 'job'
我不想为 Mark | Charles
更改 Type[Person]
因为 class PersonHandlerFactory
不应该知道 [=] 的子 class 17=].
使用边界 TypeVar,这样可以推断出正确的子class。
from typing import Dict, Type, TypeVar
class Person:
name: str
T = TypeVar("T", bound=Person)
class PersonHandlerFactory:
handlers: Dict[str, Type[Person]] = {}
@classmethod
def register(cls, handler_cls: Type[T]) -> Type[T]:
cls.handlers[handler_cls.name] = handler_cls
return handler_cls
@classmethod
def get(cls, name: str):
return cls.handlers[name]
@PersonHandlerFactory.register
class Mark(Person):
name = "Mark"
job = "scientist"
mark = Mark() # Static type of 'mark' is 'Mark' :)
PersonHandlerFactory.get
返回的 class 将始终被推断为 Type[Person]