Аннотация возвращаемого значения метода к типу его класса python

Рейтинг: 1Ответов: 3Опубликовано: 18.01.2023

Python 3.8

Есть класс с полем, тип данных которого этот же класс

class MyClass:
    def __init__(self):
        self.instance = self

В одном из методов MyClass надо вернуть это поле, то есть тип данных этого же класса и сделать аннотацию

def get_instance(self) -> MyClass: # Ошибка!
    return self.instance

Но аннотация подчёркивается с сообщением Unresolved reference 'MyClass'. При запуске интерпретатор выдаёт ошибку NameError: name 'MyClass' is not defined

Как правильно написать аннотацию к методу, который возвращает тип класса, в котором находится этот метод? (В Python 3.8)

Ответы

▲ 4Принят

Чтобы работал функционал автодополнения, т.е. PyCharm автоматически подтягивал имена методов исходя из возвращаемого типа, аннотации можно например определять так:

from typing import TypeVar

TMyClass = TypeVar("TMyClass", bound="MyClass")

class MyClass:
    def get(self) -> TMyClass:
        return

mc = MyClass()
mc.get().get()  # .get() автодополнение названия методов в PyCharm работает

можно и так

class MyClass:
    def get(self) -> 'MyClass':
        return

mc = MyClass()
mc.get().get()  # .get() автодополнение названия методов в PyCharm работает
▲ 1
from typing import Self


class MyClass:
    def __init__(self):
        self.instance = self

    def get_instance(self) -> Self:
        return self.instance

Поздновато ответил, но может кому-то пригодится.

▲ 0
MyClass = None

class MyClass:
    def __init__(self):
        ...
    def get(self) -> MyClass: # нужно сначала зарегистрироваться в пространстве имён, смотри выше 
        return self
    def __str__(self):
        return f"{self.__class__.__name__}"


mc = MyClass()
print(type(mc.get())) # <class '__main__.MyClass'>

Сама конструкция (-> MyClass) не обязывает питон вернуть вам именно этот тип данных, это просто подсказка для разработчиков.