Int*_*rer 9 python typing subclass type-hinting pycharm
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()
Run Code Online (Sandbox Code Playgroud)
Basically, in order to get everything to work out, I can do one of several things:
get_something
within Foo
SubclassOfFoo
for self.my_class
to clear things upOption #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.
我也愿意接受其他选择,因为我相信有更好的方法。
你能帮我找出处理这个问题的正确方法吗?
我试过的
为了模拟选项 #2,我尝试typing.Type
按照此处的建议使用:类型提示中的子类
但是,这对我不起作用。
my_class
您可以在类定义的开头给出属性的类型提示:
class SubclassOfFoo(Foo):
my_class: SubclassOfSomething # <- here
def get_something(self) -> SubclassOfSomething:
return SubclassOfSomething()
def do_something_special(self):
self.my_class.something_special()
Run Code Online (Sandbox Code Playgroud)
之后,Unresolved attribute reference 'something_special' for class 'Something'
PyCharm 检查就不会发出警告,因为现在my_class
已知不是SubclassOfSomething
这样Something
。
使用泛型:
from abc import ABC, abstractmethod
from typing import Generic, TypeVar
SomethingT = TypeVar('SomethingT', bound='Something')
...
class Foo(ABC, Generic[SomethingT]):
my_class: SomethingT
def __init__(self):
self.my_class = self.get_something()
@abstractmethod
def get_something(self) -> SomethingT:
pass
class SubclassOfFoo(Foo[SubclassOfSomething]):
def __init__(self):
super().__init__()
def get_something(self) -> SubclassOfSomething:
return SubclassOfSomething()
def do_something_special(self):
# inferred type of `self.my_class` will be `SubclassOfSomething`
self.my_class.something_special()
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3301 次 |
最近记录: |