【问题标题】:Optional[Type[Foo]] raises TypeError in Python 3.5.2Optional[Type[Foo]] 在 Python 3.5.2 中引发 TypeError
【发布时间】:2017-08-14 01:10:30
【问题描述】:

这段代码:

#!/usr/bin/env python

from typing import Optional, Type

class Foo(object):
    pass

class Bar(Foo):
    pass

def test_me() -> Optional[Type[Foo]]:
    print("Hi there!")
    return Bar

if __name__ == "__main__":
    test_me()

将在 3.5.2 上提高 TypeError

Traceback (most recent call last):
  File "./test.py", line 11, in <module>
    def test_me() -> Optional[Type[Foo]]:
  File "/Users/mnot/.pyenv/versions/3.5.2/lib/python3.5/typing.py", line 649, in __getitem__
return Union[arg, type(None)]
  File "/Users/mnot/.pyenv/versions/3.5.2/lib/python3.5/typing.py", line 552, in __getitem__
dict(self.__dict__), parameters, _root=True)
  File "/Users/mnot/.pyenv/versions/3.5.2/lib/python3.5/typing.py", line 512, in __new__
for t2 in all_params - {t1} if not isinstance(t2, TypeVar)):
  File "/Users/mnot/.pyenv/versions/3.5.2/lib/python3.5/typing.py", line 512, in <genexpr>
for t2 in all_params - {t1} if not isinstance(t2, TypeVar)):
  File "/Users/mnot/.pyenv/versions/3.5.2/lib/python3.5/typing.py", line 1077, in __subclasscheck__
if super().__subclasscheck__(cls):
  File "/Users/mnot/.pyenv/versions/3.5.2/lib/python3.5/abc.py", line 225, in __subclasscheck__
for scls in cls.__subclasses__():
TypeError: descriptor '__subclasses__' of 'type' object needs an argument

而它在 3.6 上运行良好。如果我将 Optional 拼写为 Union[None, Type[Foo]],也会出现同样的问题。

对于 3.5.2 是否有任何解决方法,同时仍能准确地注释返回类型?

【问题讨论】:

    标签: python python-3.x annotations python-3.5 typing


    【解决方案1】:

    这是 Python 3.5.2 中的 bug

    Optional[cls]Union[cls, type(None)] 的包装器,它使用__subclasses__() 来确定一个类是否是另一个类的子类。

    但是,Type 是 Python 3.5.2 中 type 的子类,这意味着

    Union[Type[anything], anything_else]
    

    最终会调用

    type.__subclasses__()
    

    ...这是一个问题,因为type 是一个元类,因此期望与正在寻找其子类的类一起调用,这与在常规类上调用实例方法需要您提供完全相同的方式自身的一个实例,例如str.upper('foo').

    问题在于 Python 3.5.3(以及,正如您已经注意到的,3.6)中的 fixed,通过使 Type 不再是 type 的子类。

    【讨论】:

      【解决方案2】:

      感谢零比雷埃夫斯

      我在使用 python 3.5.2 时遇到了同样的问题 我已经编辑 usr/lib/python3.5/typing.py 文件

      class Type(type, Generic[CT_co], extra=type):
      

      改为

      class Type(Generic[CT_co], extra=type):
      

      然后它修复了...

      【讨论】:

        【解决方案3】:

        我在 python 3.2 上遇到了同样的问题

        我刚刚安装了低版本的pandas

        pandas==0.24.2
        

        默认安装版本是

        pandas==0.25.1
        

        希望对您有所帮助。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-01-01
          • 1970-01-01
          • 2010-10-04
          • 2015-02-11
          • 2014-03-20
          • 1970-01-01
          • 2020-05-11
          • 2022-08-11
          相关资源
          最近更新 更多