Python Type[Type]是类对象的正确类型提示吗?
我的问题:我使用的Python Type[Type]是类对象的正确类型提示吗?,python,python-3.x,python-3.5,type-hinting,Python,Python 3.x,Python 3.5,Type Hinting,我的问题:我使用的AnyType(正如我在下面定义的)正确吗?目标是让AnyType接受任何类对象,但类对象的实例、函数类型或其他非type类型的对象应被拒绝 详情: 我有一个类似这样的类: MixinSubclsType = Type["ChildRegistryMixin"] AnyType = Type[type] # <- is this correct? class ChildRegistryMixin: """Mixin class that creates clas
AnyType
(正如我在下面定义的)正确吗?目标是让AnyType
接受任何类对象,但类对象的实例、函数类型或其他非type
类型的对象应被拒绝
详情:
我有一个类似这样的类:
MixinSubclsType = Type["ChildRegistryMixin"]
AnyType = Type[type] # <- is this correct?
class ChildRegistryMixin:
"""Mixin class that creates classes which track subclasses.
Each new child class will track its own children."""
_subclasses: Dict[Any, MixinSubclsType] = dict()
_make_reg_key: Callable[[AnyType], Any]] = lambda subcls: getattr(subcls, "__name__")
def __init_subclass__(subcls,
make_reg_key: Optional[Callable[[AnyType], Any]]] = None,
**kwargs) -> None:
# implementation here
我会使用
Type[object]
,因为Type[Type]
看起来像一个元类。但是我会将Type[object]
定义为与Type
相同,所以我只会使用Type
。这一点很好!我理解语义上的差异;当看到Type[Type]
时,查看代码的人会合理地认为是“元类!”。从功能上讲,Type[object]
和Type[Type]
不是等价的吗?@MegaIng我还建议,对于读者来说,Type
也有点像“元类”。因此,Type[object]
的语义可能更优越。但我必须考虑一下。@RickTeacheyx:Type[foo]
基本上是一个注释,表明isxinstance(x,foo)
必须为真Type[object]
是一种涵盖所有内容的类型,因为object
是类层次结构的根<代码>类型[类型]仅涵盖类对象。@切普纳:对吗?我的理解是对象本身涵盖了一切。但是Type[object]
只会覆盖类对象,因为object
的类型是Type
。。。需要在类型检查器中找到一种简单的方法来解决这个问题x:Type[foo]
表示issubclass(x,foo)
为true,而不是isinstance
x:foo
表示isinstance(x,foo)
为真。
class ChildRegistryMixin:
"""Mixin class that creates classes which track subclasses.
Each new child class will track its own children.
Usage example 1:
class RegisteredByName(ChildRegistryMixin): ...
assert ChildRegistryMixin._subclasses["RegisteredByName"] is RegisteredByName
Usage example 2:
valid_lookup = dict(ClassName="othername")
class RegisteredByPop(ChildRegistryMixin,
make_reg_key=lambda subcls:
valid_lookup.pop(subcls.__name__)):
pass
class ClassName(RegisteredByPop): ...
assert RegisteredByPop._subclasses["othername"] is ClassName
class InvalidName(RegisteredByPop): ... # <-- ERROR!
"""
_subclasses: Dict[Any, MixinSubclsType] = dict()
_make_reg_key: Callable([AnyType], Any) = lambda subcls: getattr(subcls, "__name__")
def __init_subclass__(subcls,
make_reg_key: Optional[Callable([AnyType], Any)] = None,
**kwargs) -> None:
super().__init_subclass__(**kwargs)
# for later child classes of the new class
subcls._subclasses = dict()
# child added to the reg of closest parent that is a subclass of CRB
for parent_cls in subcls.mro()[1:]:
if issubclass(parent_cls, ChildRegistryMixin):
break
else:
parent_cls = ChildRegistryMixin
# make the key
key = parent_cls._make_reg_key(subcls)
# can't have multiple child classes with same key
if key not in parent_cls._subclasses:
parent_cls._subclasses[key] = subcls
else:
raise ChildRegistryError(f"Attempted to overwrite the "
f"child class key {key!r} in the "
f"{parent_cls.__name__} registry")
# inherit the subclass' key maker from parent if one was not provided
subcls._make_reg_key = parent_cls._make_reg_key if make_reg_key is None\
else make_reg_key