首页 > 解决方案 > Python类型在方法中提示自己的类

问题描述

编辑:我注意到人们评论不应该使用类型提示__eq__,并且授予它不应该。但这不是我的问题的重点。我的问题是为什么类不能在方法参数中用作类型提示,但可以在方法本身中使用?


在使用 PyCharm 时,Python 类型提示已被证明对我非常有用。但是,当尝试在其方法中使用类自己的类型时,我遇到了我觉得奇怪的行为。

例如:

class Foo:

    def __init__(self, id):
        self.id = id
        pass

    def __eq__(self, other):
        return self.id == other.id

在这里,键入 时,不会自动提供other.该属性。id我希望通过__eq__如下定义来解决它:

    def __eq__(self, other: Foo):
        return self.id == other.id

但是,这给出了NameError: name 'Foo' is not defined. 但是当我在方法中使用类型时,id在编写后提供other.

    def __eq__(self, other):
        other: Foo
        return self.id == other.id

我的问题是,为什么不能使用类自己的类型来提示参数,而在方法中却可以?

标签: pythonpython-3.x

解决方案


该名称Foo尚不存在,因此您需要'Foo'改用。(mypy和其他类型检查器应将此视为前向参考。)

def __eq__(self, other: 'Foo'):
    return self.id == other.id

或者,您可以使用

from __future__ import annotations

这可以防止评估所有注释并将它们简单地存储为字符串以供以后参考。(这将是 Python 3.10 中的默认设置。)

最后,正如评论中也指出的那样,首先__eq__不应以这种方式暗示。第二个参数应该是任意对象;如果您不知道如何将您的实例与它进行比较,您将返回。(谁知道呢,也许知道如何将自己与您的实例进行比较。如果返回,那么 Python 会尝试。)NotImplementedFoo.__eq__(Foo(), Bar())NotImplementedBar.__eq__(Bar(), Foo())

from typing import Any


def __eq__(self, other: Any) -> bool:
    if isinstance(other, Foo):
        return self.id == other.id
    return NotImplemented

或使用鸭式打字,

def __eq__(self, other: Any) -> bool:
    # Compare to anything with an `id` attribute
    try:
        return self.id == other.id
    except AttributeError:
        return NotImplemented

在任何一种情况下,Any提示都是可选的。


推荐阅读