简体   繁体   English

Python 类型在方法中提示自己的 class

[英]Python type hinting own class in method

Edit : I notice people commenting about how the type hint should not be used with __eq__ , and granted, it shouldn't.编辑:我注意到人们评论类型提示不应该与__eq__一起使用,并且授予,它不应该。 But that's not the point of my question.但这不是我的问题的重点。 My question is why can't the class be used as type hint in the method parameters , but can be used in the method itself ?我的问题是为什么不能将 class 用作方法参数中的类型提示,但可以在方法本身中使用?


Python type hinting has proven very useful for me when working with PyCharm.在使用 PyCharm 时,Python 类型提示已被证明对我非常有用。 However, I've come across behaviour I find strange, when trying to use a class' own type in its methods.但是,当尝试在其方法中使用类自己的类型时,我遇到了我觉得奇怪的行为。

For example:例如:

class Foo:

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

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

Here, when typing other.在这里,当键入other. , the property id is not offered automatically. , 属性id不会自动提供。 I was hoping to solve it by defining __eq__ as follows:我希望通过如下定义__eq__来解决它:

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

However, this gives NameError: name 'Foo' is not defined .但是,这给出了NameError: name 'Foo' is not defined But when I use the type within the method, id is offered after writing other.但是当我在方法中使用类型时,在编写other.类型之后会提供id :

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

My question is, why is it not possible to use the class' own type for type hinting the parameters, while it is possible within the method?我的问题是,为什么不能使用类自己的类型来提示参数,而在方法中却可以?

The name Foo doesn't yet exist, so you need to use 'Foo' instead.名称Foo尚不存在,因此您需要使用'Foo'代替。 ( mypy and other type checkers should recognize this as a forward reference.) mypy和其他类型检查器应该将其识别为前向引用。)

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

Alternately, you can use或者,您可以使用

from __future__ import annotations

which prevents evaluation of all annotations and simply stores them as strings for later reference.这可以防止评估所有注释并将它们简单地存储为字符串以供以后参考。 (This will be the default in Python 3.10.) (这将是 Python 3.10 中的默认设置。)

Finally, as also pointed out in the comments, __eq__ should not be hinted this way in the first place.最后,正如评论中还指出的那样,首先应该以这种方式暗示__eq__ The second argument should be an arbitrary object;第二个参数应该是任意的 object; you'll return NotImplemented if you don't know how to compare your instance to it.如果您不知道如何将您的实例与它进行比较,您将返回NotImplemented (Who knows, maybe it knows how to compare itself to your instance. If Foo.__eq__(Foo(), Bar()) returns NotImplemented , then Python will try Bar.__eq__(Bar(), Foo()) .) (谁知道呢,也许知道如何将自己与您的实例进行比较。如果Foo.__eq__(Foo(), Bar())返回NotImplemented ,那么 Python 将尝试Bar.__eq__(Bar(), Foo()) 。)

from typing import Any


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

or using duck-typing,或使用鸭式打字,

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

In either case, the Any hint is optional.在任何一种情况下, Any提示都是可选的。

since you dont specify the type of the input the ide cant understand what you are dealing with.由于您没有指定输入的类型,因此 ide 无法理解您在处理什么。

try:尝试:

class Foo:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM