public interface IInterface
{
void show();
}
public class MyClass : IInterface
{
#region IInterface Members
public void show()
{
Console.WriteLine("Hello World!");
}
#endregion
}
Как мне реализовать Python-эквивалент этого кода на C #?
class IInterface(object):
def __init__(self):
pass
def show(self):
raise Exception("NotImplementedException")
class MyClass(IInterface):
def __init__(self):
IInterface.__init__(self)
def show(self):
print 'Hello World!'
Это хорошая идея?? Пожалуйста, приведите примеры в своих ответах.
raise NotImplementedError
это то, чтоshow
тело должно быть - не имеет смысла поднимать полностью универсальный,Exception
когда Python определяет совершенно конкретный встроенный! -)Ответы:
Как уже упоминалось другим здесь:
Интерфейсы не нужны в Python. Это потому, что Python имеет правильное множественное наследование, а также ducktyping, что означает, что в тех местах, где вы должны иметь интерфейсы в Java, вам не нужно иметь их в Python.
Тем не менее, есть еще несколько вариантов использования интерфейсов. Некоторые из них охватываются абстрактными базовыми классами Pythons, представленными в Python 2.6. Они полезны, если вы хотите создать базовые классы, которые не могут быть созданы, но предоставляют определенный интерфейс или часть реализации.
Другое использование, если вы как-то хотите указать, что объект реализует определенный интерфейс, и вы можете использовать ABC для этого тоже, создав подклассы из них. Другой способ - это zope.interface, модуль, который является частью архитектуры компонентов Zope, действительно классная структура компонентов. Здесь вы не наследуете интерфейсы, а вместо этого помечаете классы (или даже экземпляры) как реализующие интерфейс. Это также может быть использовано для поиска компонентов в реестре компонентов. Очень круто!
источник
Использование модуля abc для абстрактных базовых классов, кажется, делает свое дело.
источник
if not server.version() == '1.0': raise ...
? Я действительно не понимаю эту линию. Объяснение будет приветствоваться.Интерфейс поддерживает Python 2.7 и Python 3.4+.
Для установки интерфейса вам необходимо
Пример кода:
источник
Реализация интерфейсов с абстрактными базовыми классами намного проще в современном Python 3, и они служат в качестве контракта интерфейса для расширений плагинов.
Создайте интерфейс / абстрактный базовый класс:
Создайте нормальный подкласс и переопределите все абстрактные методы:
При желании вы можете иметь общую реализацию в абстрактных методах, например
create_sale_invoice()
, вызывая ееsuper()
явно в подклассе, как указано выше.Создание экземпляра подкласса, который не реализует все абстрактные методы, завершается неудачей:
Вы также можете иметь абстрактные свойства, статические и классовые методы, комбинируя соответствующие аннотации с
@abstractmethod
.Абстрактные базовые классы отлично подходят для реализации систем на основе плагинов. Все импортированные подклассы класса доступны через
__subclasses__()
, поэтому, если вы загружаете все классы из каталога плагинов с помощьюimportlib.import_module()
и если они подклассируют базовый класс, у вас есть прямой доступ к ним через__subclasses__()
и вы можете быть уверены, что контракт интерфейса применяется для всех их во время реализации.Вот реализация загрузки плагина для
AccountingSystem
приведенного выше примера:Затем вы можете получить доступ к объекту плагина системы учета через
AccountingSystem
класс:(Вдохновлено этим сообщением PyMOTW-3 .)
источник
Существуют сторонние реализации интерфейсов для Python (наиболее популярными являются Zope , также используемые в Twisted ), но чаще всего программисты Python предпочитают использовать более богатую концепцию, известную как «Абстрактный базовый класс» (ABC), которая сочетает интерфейс с возможность иметь некоторые аспекты реализации там тоже. ABC особенно хорошо поддерживаются в Python 2.6 и более поздних версиях, см. PEP , но даже в более ранних версиях Python они обычно рассматриваются как «путь» - просто определите класс, некоторые из методов которого возникают,
NotImplementedError
чтобы подклассы были заметьте, что им лучше переопределить эти методы! -)источник
Примерно так (может не работать, так как у меня нет Python):
источник
__init__(self)
с конструктором?abc.ABC
это намного лучше, чем повышениеNotImplementedError
- создание экземпляраabc.ABC
подкласса, который не реализует все абстрактные методы, рано или поздно завершается неудачей, поэтому вы защищены от ошибок. Смотрите мой ответ ниже, чтобы узнать, как выглядит ошибка.Насколько я понимаю, интерфейсы не нужны в динамических языках, таких как Python. В Java (или C ++ с его абстрактным базовым классом) интерфейсы являются средством для обеспечения того, что, например, вы передаете правильный параметр, способный выполнять множество задач.
Например, если у вас есть наблюдатель и наблюдаемый, наблюдаемый заинтересован в подписке объектов, которые поддерживают интерфейс IObserver, который, в свою очередь, имеет
notify
действие. Это проверяется во время компиляции.В Python нет такого понятия, как
compile time
поиск методов выполняется во время выполнения. Кроме того, можно переопределить поиск с помощью магических методов __getattr __ () или __getattribute __ (). Другими словами, вы можете передать в качестве наблюдателя любой объект, который может вернуть вызываемый при доступе кnotify
атрибуту.Это приводит меня к выводу, что интерфейсы в Python существуют - просто их применение откладывается до момента, когда они фактически используются.
источник