Как написать интерфейс (контракт) для существования свойства объекта (атрибута) в python? - PullRequest
5 голосов
/ 07 июня 2019

Я бы хотел заключить договор на параметр какой-либо функции, чтобы у объекта параметра было определенное свойство.Я понимаю, что 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, могла отлавливать ошибки реализации, когда класс не подчиняется определенному интерфейсу или контракту, для которого требуется, чтобы экземпляр параметра имел какое-либо свойство.

Что такоепитонический (или не столь питонский) способ достичь этого?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...