Как определить подсказку типа для экземпляра класса с динамически добавляемым атрибутом?

#python #type-hinting

#python #подсказка типа

Вопрос:

Рассмотрим этот импортированный класс и функцию. Я не могу их редактировать, и их нецелесообразно исправлять:

 # Code I can't change

class Person:
    def __init__(self, age: int):
        self.age = age

def get_person() -> Person:
    return Person(42)
 

Я оборачиваю get_person свою собственную функцию и изменяю Person объект. Я должен вызвать / обернуть get_person , поскольку нецелесообразно воспроизводить логику внутри этой функции.

 # My code

def get_person_with_name() -> ???:
    person = get_person()
    person.name = 'Tim'
    return person
 

Как мне ввести подсказку возвращаемого значения get_person_with_name в « Person объект, но также с атрибутом name»? И как мне сделать это правильно, чтобы проверка типа и завершение кода учитывали тип измененного объекта?

Комментарии:

1. «объект Person, но также с атрибутом name», который на самом деле не является типом. Динамическое добавление атрибутов в значительной степени противоречит номинальной типизации. Возможно, вы можете использовать что-то вроде a Protocol , которое позволяет для структурного подтипа указывать «тип, который имеет атрибут name»

2. Если я знаю, что всегда буду добавлять атрибут name, то не могу ли я просто определить новый тип (возможно, на основе Person ) и сказать, что эта функция каким-то образом соответствует этому новому типу?

3. Почему бы просто не создать подкласс Person, определив класс NamedPerson, который определяет атрибут «name»? Я полагаю, что переход по этому маршруту не определяет «динамически добавляемый атрибут», но я не считаю, что это то, что делает ваша get_person_with_name функция.

4. Нет … возвращаемый объект будет иметь тип NamedPerson , но также будет удовлетворять любому использованию, в котором Person ожидается объект. Это основная природа объектной ориентации, которую естественным образом поддерживает подсказка типа.

5. Динамическое добавление подобных атрибутов намеренно запрещено в системе статических типов. Это прекрасно в реальной системе типов среды выполнения, но для статической типизации? Нет. Для того, что вы хотите сделать, нет аннотации. Если вы хотите делать вещи, которые не являются статически допустимыми, вам, вероятно, вообще не следует использовать аннотации типов.