Python 输入 class 的 Union 及其实例
Python typing Union of class and it's instance
说我有
class Foo:
pass
并且我想编写一个可以接受 Foo 实例或某些 Foo 子类(不是实例)的函数。所以我写了
def bar(o: Union[Foo, Type[Foo]]):
print(1)
并得到这样的错误:
TypeError Traceback (most recent call last) <ipython-input-161-2a8355efa688> in <module>()
----> 1 def bar(o: Union[Foo, Type[Foo]]):
2 print(1)
3
/usr/lib/python3.5/typing.py in __getitem__(self, parameters)
550 parameters = (parameters,)
551 return self.__class__(self.__name__, self.__bases__,
--> 552 dict(self.__dict__), parameters, _root=True)
553
554 def __eq__(self, other):
/usr/lib/python3.5/typing.py in __new__(cls, name, bases, namespace, parameters, _root)
510 continue
511 if any(isinstance(t2, type) and issubclass(t1, t2)
--> 512 for t2 in all_params - {t1} if not isinstance(t2, TypeVar)):
513 all_params.remove(t1)
514 # It's not a union if there's only one type left.
/usr/lib/python3.5/typing.py in <genexpr>(.0)
510 continue
511 if any(isinstance(t2, type) and issubclass(t1, t2)
--> 512 for t2 in all_params - {t1} if not isinstance(t2, TypeVar)):
513 all_params.remove(t1)
514 # It's not a union if there's only one type left.
/usr/lib/python3.5/typing.py in __subclasscheck__(self, cls) 1075 return True 1076 # If we break out of the loop, the superclass gets a chance.
-> 1077 if super().__subclasscheck__(cls): 1078 return True 1079 if self.__extra__ is None or isinstance(cls, GenericMeta):
/home/alexey/dev/gcore/django/lib/python3.5/abc.py in
__subclasscheck__(cls, subclass)
223 return True
224 # Check if it's a subclass of a subclass (recursive)
--> 225 for scls in cls.__subclasses__():
226 if issubclass(subclass, scls):
227 cls._abc_cache.add(subclass)
TypeError: descriptor '__subclasses__' of 'type' object needs an argument
是否无法在 python 中指定该类型,或者我使用了错误的方法?
参见typing/issue 266。这已得到修复,不再出现在 Python.
的更新版本中
使用 Python 3.6.1
,函数编译良好并且注释存储正确:
>>> def bar(o: Union[Foo, Type[Foo]]):
... print(1)
>>> typing.get_type_hints(bar)
{'o': typing.Union[__main__.Foo, typing.Type[__main__.Foo]]}
说我有
class Foo:
pass
并且我想编写一个可以接受 Foo 实例或某些 Foo 子类(不是实例)的函数。所以我写了
def bar(o: Union[Foo, Type[Foo]]):
print(1)
并得到这样的错误:
TypeError Traceback (most recent call last) <ipython-input-161-2a8355efa688> in <module>()
----> 1 def bar(o: Union[Foo, Type[Foo]]):
2 print(1)
3
/usr/lib/python3.5/typing.py in __getitem__(self, parameters)
550 parameters = (parameters,)
551 return self.__class__(self.__name__, self.__bases__,
--> 552 dict(self.__dict__), parameters, _root=True)
553
554 def __eq__(self, other):
/usr/lib/python3.5/typing.py in __new__(cls, name, bases, namespace, parameters, _root)
510 continue
511 if any(isinstance(t2, type) and issubclass(t1, t2)
--> 512 for t2 in all_params - {t1} if not isinstance(t2, TypeVar)):
513 all_params.remove(t1)
514 # It's not a union if there's only one type left.
/usr/lib/python3.5/typing.py in <genexpr>(.0)
510 continue
511 if any(isinstance(t2, type) and issubclass(t1, t2)
--> 512 for t2 in all_params - {t1} if not isinstance(t2, TypeVar)):
513 all_params.remove(t1)
514 # It's not a union if there's only one type left.
/usr/lib/python3.5/typing.py in __subclasscheck__(self, cls) 1075 return True 1076 # If we break out of the loop, the superclass gets a chance.
-> 1077 if super().__subclasscheck__(cls): 1078 return True 1079 if self.__extra__ is None or isinstance(cls, GenericMeta):
/home/alexey/dev/gcore/django/lib/python3.5/abc.py in
__subclasscheck__(cls, subclass)
223 return True
224 # Check if it's a subclass of a subclass (recursive)
--> 225 for scls in cls.__subclasses__():
226 if issubclass(subclass, scls):
227 cls._abc_cache.add(subclass)
TypeError: descriptor '__subclasses__' of 'type' object needs an argument
是否无法在 python 中指定该类型,或者我使用了错误的方法?
参见typing/issue 266。这已得到修复,不再出现在 Python.
的更新版本中使用 Python 3.6.1
,函数编译良好并且注释存储正确:
>>> def bar(o: Union[Foo, Type[Foo]]):
... print(1)
>>> typing.get_type_hints(bar)
{'o': typing.Union[__main__.Foo, typing.Type[__main__.Foo]]}