Код: Выделить всё
foo.py
Однако, если foo< /code> — это экземпляр класса Foo, а bar — это экземпляр класса Bar, и я пытаюсь добавить bar + foo в модуль foo, Boo будет обрабатывать foo как __main__.Foo и выдавать ошибку TypeError. Рассматриваемый код можно суммировать следующим образом:
Код: Выделить всё
from typing import Union, Any
import bar as b
FooBar = Union['Foo', 'b.Bar']
class Foo:
message: str
def __init__(self, message: str) -> None:
self.message = message
def __add__(self, other: Any) -> 'Foo':
if not isinstance(other, (Foo, b.Bar)):
raise TypeError('can only add Foo and Bar')
return Foo(' '.join((self.message, other.message)))
def test():
foo = Foo('Jalim')
bar = b.Bar('Rabei')
foobar = foo + bar # works just fine
print(foobar.message)
barfoo = bar + foo # raises TypeError because it receives __main__.Foo
print(barfoo.message)
if __name__ == '__main__':
test()
Код: Выделить всё
from typing import Union, Any
import foo
FooBar = Union['foo.Foo', 'Bar']
class Bar:
message: str
def __init__(self, message: str) -> None:
self.message = message
def __add__(self, other: Any) -> 'Bar':
if not isinstance(other, (foo.Foo, Bar)):
print(f'{type(other) = }')
raise TypeError('can only add Foo and Bar')
return Bar(''.join((self.message, other.message)))
Сначала я попробовал использовать псевдоним типа FooBar вместо кортежа (Foo , бар.Бар). Однако, поскольку FooBar на самом деле не содержит типов, а вместо этого содержит ForwardRef, его нельзя использовать в isinstance. Я также не могу объединить Foo и Bar в Union, потому что это создаст циклический импорт.
Подробнее здесь: https://stackoverflow.com/questions/791 ... s-main-foo