Я бы хотел заключить договор на параметр какой-либо функции, чтобы у объекта параметра было определенное свойство.Я понимаю, что Python не является строго типизированным языком, но иногда бывает полезно иметь контракты и интерфейсы.У Python теперь есть подсказки типов, и это здорово, поэтому мы можем сделать это:
def myfunc(myparam: MyType) -> SomeType:
myparam.myprop # this should exist
Но как я могу сказать, что MyType должен иметь определенное свойство объекта (myprop) без вставки утверждений и выдачи исключений во время выполнения?Я мог бы определить абстрактные классы с помощью метаклассов abc, которые можно использовать в качестве интерфейсов.
from abc import ABC, abstractmethod
class MyInterface(ABC):
@property
@abstractmethod
def myprop(self) -> int: pass
Теперь где-то в коде я могу определить MyType как:
class MyType(MyInterface):
myprop = 8
Это работает, но myprop это свойство класса , а не свойство объекта (атрибут).Конечно, я мог бы сделать это:
class MyType(MyInterface):
myprop = 0
def __init__(self):
self.myprop = 8
Хорошо, но мне пришлось определить (ненужное) свойство класса («статическое») и эффективно скрыть его с помощью свойства объекта.Не очень чисто.Более того, теперь у меня есть значение по умолчанию для myprop, которое не то, что я хочу.Но если я сделаю это:
class MyType(MyInterface):
myprop = None # wrong type here
def __init__(self):
self.myprop = 8
, это неправильно, потому что myprop должно быть int и не может быть None, что правильно перехватывается линтером.Должно быть свойство объекта без свойства класса.
Цель состоит в том, чтобы статическая проверка, такая как mypy, могла отлавливать ошибки реализации, когда класс не подчиняется определенному интерфейсу или контракту, для которого требуется, чтобы экземпляр параметра имел какое-либо свойство.
Что такоепитонический (или не столь питонский) способ достичь этого?