Python:如何覆盖子类中实例属性的类型提示? [英] Python: how to override type hint on an instance attribute in a subclass?

查看:36
本文介绍了Python:如何覆盖子类中实例属性的类型提示?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在深入研究之前,我的问题是:如何在子类中使用类型提示来为实例属性指定不同的类型?

如果您不清楚这意味着什么,请阅读下面的内容,我在此处草拟了一个示例来阐明问题.

<小时>

完整说明

我有一个抽象类Foo,还有一个Foo的子类,叫做SubclassOfFoo.

Foo 有一个抽象方法 get_something 返回一个 Something 类型的对象.

Something 有一个名为 SubclassOfSomething 的子类.SubclassOfSomething 有一个额外的方法 something_special.

SubclassOfFoo 覆盖 get_something 以返回 SubclassOfSomething 类型的对象.然后,SubclassOfFoo 尝试使用 SubclassOfSomething 的方法 something_special.

但是,目前我的 PyCharm 的检查报告了 未解析的属性引用 'Something_special' 类的 'Something'.我正在尝试找出解决此问题的正确方法.

这一切都非常令人困惑,所以我做了一个很好的小代码片段来帮助这里:

<预><代码>从 abc 导入 ABC,抽象方法类东西:def __init__(self):self.attr = 0类 SubclassOfSomething(Something):def __init__(self):东西.__init__(self)def something_special(self):self.attr = 1类 Foo(ABC):def __init__(self):self.my_class = self.get_something()@抽象方法def get_something(self) ->某物:经过类 SubclassOfFoo(Foo):def __init__(self):Foo.__init__(self)def get_something(self) ->子类的东西:返回 SubclassOfSomething()def do_something_special(self):self.my_class.something_special()

基本上,为了让一切顺利,我可以做以下几件事之一:

  1. 去除Foo
  2. get_something返回的类型提示
  3. SubclassOfFoo 中为 self.my_class 使用类型提示来清除问题
  4. 使用泛型?

选项#1 是我试图避免的

选项#2 还不错,但我想不通

选项 #3 也是一个选项.

我也愿意接受其他选择,因为我相信有更好的方法.

你能帮我找出处理这个问题的正确方法吗?

<小时>

我的尝试

为了模拟选项 #2,我尝试使用 typing.Type 如下建议:类型提示中的子类

但是,这对我不起作用.

解决方案

您可以在类定义开头的 my_class 属性上给出类型提示:

class SubclassOfFoo(Foo):my_class: SubclassOfSomething # <- 这里def get_something(self) ->子类的东西:返回 SubclassOfSomething()def do_something_special(self):self.my_class.something_special()

之后没有警告 Unresolved attribute reference 'something_special' for class 'Something' 从 PyCharm 检查中,因为现在 my_class 已知是 SubclassOfSomething 不是 Something.

Before you dive in, here is my question: how can I use type hints in a subclass to specify a different type on an instance attribute?

If you are unclear on what that means, read below, where I have drawn up an example to clarify things.


Full Explanation

I have an abstract class Foo, and a subclass of Foo called SubclassOfFoo.

Foo has an abstract method get_something that returns an object of type Something.

Something has a subclass called SubclassOfSomething. SubclassOfSomething has an additional method something_special.

SubclassOfFoo overrides get_something to return an object of type SubclassOfSomething. Then, SubclassOfFoo tries to use SubclassOfSomething's method something_special.

However, currently my PyCharm's inspections are reporting Unresolved attribute reference 'something_special' for class 'Something'. I am trying to figure out the correct way to fix this.

This is all very confusing, so I have made a nice little code snippet to help here:


from abc import ABC, abstractmethod


class Something:
    def __init__(self):
        self.attr = 0


class SubclassOfSomething(Something):
    def __init__(self):
        Something.__init__(self)

    def something_special(self):
        self.attr = 1


class Foo(ABC):
    def __init__(self):
        self.my_class = self.get_something()

    @abstractmethod
    def get_something(self) -> Something:
        pass


class SubclassOfFoo(Foo):
    def __init__(self):
        Foo.__init__(self)

    def get_something(self) -> SubclassOfSomething:
        return SubclassOfSomething()

    def do_something_special(self):
        self.my_class.something_special()

Basically, in order to get everything to work out, I can do one of several things:

  1. Remove the type hint on the return of get_something within Foo
  2. Use a type hint in SubclassOfFoo for self.my_class to clear things up
  3. Use generics?

Option #1 is what I am trying to avoid

Option #2 is not bad, but I can't figure it out

Option #3 is also an option.

I am also open to other options, as I am sure there is a better way.

Can you please help me figure out the correct way to handle this?


What I Have Tried

To emulate option #2, I tried using typing.Type as suggested here: Subclass in type hinting

However, this was not working for me.

解决方案

You can give a type hint on my_class attribute in the beginning of class definition:

class SubclassOfFoo(Foo):
    my_class: SubclassOfSomething  # <- here

    def get_something(self) -> SubclassOfSomething:
        return SubclassOfSomething()

    def do_something_special(self):
        self.my_class.something_special()

After that there is no warning Unresolved attribute reference 'something_special' for class 'Something' from PyCharm inspection because now my_class is known to be SubclassOfSomething not Something.

这篇关于Python:如何覆盖子类中实例属性的类型提示?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆