gpt4 book ai didi

python - 如何在 Python 元类中键入 __new__ 方法让 mypy 开心

转载 作者:行者123 更新时间:2023-12-03 16:20:44 24 4
gpt4 key购买 nike

我正在尝试输入 __new__ Python 中元类中的方法,以便它取悦 mypy。代码将是这样的(取自 pep-3115 - “Python 3000 中的元类”并精简了一点):

from __future__ import annotations

from typing import Type


# The metaclass
class MetaClass(type):

# The metaclass invocation
def __new__(cls: Type[type], name: str, bases: tuple, classdict: dict) -> type:
result = type.__new__(cls, name, bases, classdict)
print('in __new__')
return result


class MyClass(metaclass=MetaClass):
pass
有了这个,mypy 提示说, Incompatible return type for "__new__" (returns "type", but must return a subtype of "MetaClass") ,指向线 def __new__ .
我也试过:
def __new__(cls: Type[MetaClass], name: str, bases: tuple, classdict: dict) -> MetaClass:
然后 mypy 提示(关于 return result 行): Incompatible return value type (got "type", expected "MetaClass") .
我也尝试过使用类型 var ( TSubMetaclass = TypeVar('TSubMetaclass', bound='MetaClass') ),结果与使用 MetaClass 相同.
使用 super().__new__而不是 type.__new__给出了类似的结果。
什么是正确的方法呢?

最佳答案

首先,返回类型是MetaClass ,不是 type .其次,您需要显式转换返回值,因为 type.__new__不知道它正在返回 MetaClass 的实例. (它的具体返回类型由它的第一个参数决定,它不是静态已知的。)

from __future__ import annotations

from typing import Type, cast


# The metaclass
class MetaClass(type):

# The metaclass invocation
def __new__(cls: Type[type], name: str, bases: tuple, classdict: dict) -> MetaClass:
result = type.__new__(cls, name, bases, classdict)
print('in __new__')
return cast(MetaClass, result)


class MyClass(metaclass=MetaClass):
pass

使用 super ,需要调整 cls的静态类型范围。
class MetaClass(type):

# The metaclass invocation
def __new__(cls: Type[MetaClass], name: str, bases: tuple, classdict: dict) -> MetaClass:
result = super().__new__(name, bases, classdict)
print('in __new__')
return cast(MetaClass, result)

关于python - 如何在 Python 元类中键入 __new__ 方法让 mypy 开心,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63054541/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com