Есть ли в Python интерфейсы в стиле C # / Java? - PullRequest
7 голосов
/ 27 сентября 2011

Я несколько месяцев работал программистом на C # и привык к идее generics / templates интерфейсов, которые я мог передать в библиотеку, не заботясь о том, как был создан объект.

Я собираюсь начать относительно большой проект, возможно, на python (я уже писал много на python, но в основном это мой собственный код для анализа данных и т. Д.), И мне было интересно, существует ли подобная концепция в этот язык? Я попробовал поискать в Google и не придумал много.

Если ответ «нет», это нормально, но в таком случае, что люди обычно делают вместо этого?

Ответы [ 5 ]

17 голосов
/ 27 сентября 2011

Если ответ «нет», это нормально, но в таком случае, что люди обычно делают вместо этого?

Duck Typing .

Важно подойти к Python, бросив технический багаж на C #.

Изучение Python как нового языка. Не пытайтесь отображать понятия между Python и C #. Так лежит безумие.


«ИНТЕРФЕЙСЫ, а не дженерики или шаблоны»

Не имеет значения. Вся эта технология объявления статических типов не нужна. В этом случае приведение типов к нарушению правил также не требуется.

5 голосов
/ 27 сентября 2011

Мое понимание интерфейсов исходит от Java, так что, надеюсь, это достаточно близко к тому, что вы имеете в виду ...

Нет синтаксического способа утверждать, что конкретный объект имеет набор методов и полей, потому что Python использует динамическая печать / утка .Если вы хотите проверить, есть ли у объекта определенный метод или поле, вы можете:

  • копаться в нем с отражением (это самая большая работа)
  • Проверьте, что вы хотите в его __dict__ (словарь всех членов объекта).MyObj.__dict__.hasKey(o) это то, что вы хотите, я думаю.(довольно просто)
  • Просто используйте объект и поверьте, что вы, ваши коллеги-разработчики или ваши пользователи дали вам подходящий объект.(Максимально легко, но опасно)
  • Или, сделайте вышеописанное и оберните его в блок try / кроме.(Это будет знакомо Java-программистам)

Разработка сложного набора классов в Python - это совсем не то же самое, что делать в C-подобных языках, поэтому будьте готовы к тому, что вы можетенеудобно с (как вариант 3, выше).Удачи!

5 голосов
/ 27 сентября 2011

Python динамически типизируется, поэтому (в большинстве случаев) нет необходимости в дженериках / шаблонах.

4 голосов
/ 28 сентября 2011

Если вы говорите строго о C # / Java-подобном интерфейсе, то ответ прост. Это понятия, которые относятся к статически типизированным языкам и на самом деле не применяются к динамическим языкам, таким как Python.

Обычный подход к питону - доверять объектам, которые вы получаете, и предполагать, что они обладают необходимыми чертами, которые вам нужны. В противном случае вы можете ожидать ошибки времени выполнения, которые могут быть обработаны или оставлены для вызывающей стороны. Это соответствует общей динамической природе языка: если что-то пойдет не так, вы можете ожидать, что оно всплывет во время выполнения.

Интерфейсы из Java или C #, с другой стороны, являются средством проверки необходимых предварительных условий (то есть объектов, имеющих определенные методы) во время компиляции . Это (возможно) заменяет некоторую гибкость времени выполнения для повышения безопасности проверок во время компиляции.

Обратите внимание, что это не означает, что любая концепция интерфейса не имеет места в динамически типизированном языке. На самом деле, в Python есть слегка размытое понятие «мета-типы», такие как итерации, которые часто проверяются, например, проверяя наличие определенного метода (ов):

def process_sequence(seq):
    if not hasattr(seq, '__iter__'):
        seq = [seq] # turn single element into iterable
    for elem in seq:
        process_element(elem)

Это концептуально похоже на не-манифестные интерфейсы языка Go. Если вы хотите иметь свою собственную итерацию, вы просто реализуете метод __iter__ - без явного указания, что будет реализовывать его (как в Java, где вы наследуете от List класса). Если кто-то захочет проверить, действительно ли ваш объект является итеративным, он может проверить, действительно ли выполнен «контракт», т. Е. Имеющий метод __iter__. Это то, что андроникус описал в своем ответе.

Как бесстыдный плагин, я могу указать на библиотеку pyduck , которую я реализую. Он нацелен на то, чтобы упростить (и, возможно, даже стандартизировать) проверку таких «контрактов» (путем отражения) и сделать ее несколько более надежной.

3 голосов
/ 27 сентября 2011

zope.interface

Но большинство людей не используют его.

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