методе run как-то разрулить тип и сказать что self.foo_arg имеет тип BarArg а не FooArg?
import abc
from dataclasses import dataclass
@dataclass
class FooArg:
foo: int
class Foo:
def __init__(self, foo_arg: FooArg) -> None:
self.foo_arg = foo_arg
@abc.abstractmethod
def run(self) -> None:
pass
@dataclass
class BarArg(FooArg):
bar: int
class Bar(Foo):
def __init__(self, bar_arg: BarArg) -> None:
super().__init__(bar_arg)
def run(self) -> None:
print(self.foo_arg)
def main():
bar = Bar(BarArg(555, 777))
bar.run()
if __name__ == "__main__":
main()
print("done")
только так? self.foo_arg = cast(BarArg, bar_arg) или можно более красиво это сделать?
Убирать инит из базового класса просто
Пример не полный, сейчас дополню
ещё вариант завести дополнительный атрибут под bar_arg
скорее такой юзкейс: import abc from dataclasses import dataclass from typing import cast @dataclass class FooArg: foo: int class Foo: def __init__(self, foo_arg: FooArg) -> None: self.foo_arg = foo_arg def _before_run(self): print(self.foo_arg.foo) @abc.abstractmethod def _do_run(self) -> None: pass def run(self) -> None: self._before_run() self._do_run() @dataclass class BarArg(FooArg): bar: int class Bar(Foo): def __init__(self, bar_arg: BarArg) -> None: super().__init__(bar_arg) self.foo_arg = cast(BarArg, bar_arg) def _do_run(self) -> None: print(self.foo_arg) def main(): bar = Bar(BarArg(555, 777)) bar.run() if __name__ == "__main__": main() print("done")
FooT = TypeVar("FooT", bound=FooArg) class Foo(Generic[FooT]): def __init__(self, foo_arg: FooT) -> None: self.foo_arg = foo_arg class Bar(Foo[FooBar]):
А новый синтакис
подожду пока ВСЕ поддерживаемые версии будут его уметь
Ахахахахаххахаа
кароче говоря, ты на 3.10 надолго еще
он там на 3.8 вроде
Крутяк, все работает, спасибо
А как это будет в новом синтаксисе?
class Foo[T: FooArg]: def __init__(self, foo_arg: T) -> None: self.foo_arg = foo_arg class Bar(Foo[BarArg]): pass
А где про этот синтаксис прочитать?
Обсуждают сегодня