Подтвердить что ты не робот

Какая версия Python для "Код против интерфейса, а не объекта"?

Вдохновленный большим вопросом (и множеством отличных ответов) от здесь.

Является ли утверждение "Код против интерфейса, а не объекта" какое-либо значение в Python?

Я ищу ответы, подобные тем, которые были в Оригинальном вопросе, но с фрагментами и мыслями Python.

4b9b3361

Ответ 1

"Код против интерфейса, а не объекта" не делает буквального смысла в Python, потому что язык не имеет функции интерфейса. Грубый эквивалент Python - "использование утиного набора". Если вы хотите увидеть, является ли объект утиной, другими словами, вы должны проверить, имеет ли он метод quack() или еще лучше попытаться quack() и обеспечить соответствующую обработку ошибок, а не проверить, является экземпляром Duck.

Обычные типы уток в Python - это файлы (ну, действительно, файловые объекты), сопоставления (dict -подобные объекты), callables (функционально-подобные объекты), последовательности (list -подобные объекты) и iterables (вещи, которые вы можете перебрать, которые могут быть контейнерами или генераторами).

В качестве примера, функции Python, которые хотят получить файл, обычно с удовольствием принимают объект, который реализует методы file, в которых он нуждается; он не должен быть получен из класса file. Например, для использования объекта в качестве стандартного, главное, что он понадобится, это метод write() (и, возможно, flush() и close(), который на самом деле ничего не должен делать). Аналогично, вызываемым является любой объект, который имеет метод __call__(); он не должен быть получен из типа функции (на самом деле вы не можете получить из типа функции).

Вы должны придерживаться аналогичного подхода. Проверьте методы и атрибуты, необходимые для того, что вы собираетесь делать с объектом. Еще лучше документируйте то, что вы ожидаете, и предположите, что тот, кто звонит вам, не является полным doofus. (Если они дают вам объект, который вы не можете использовать, они, безусловно, будут достаточно быстро распознавать это из ошибок, которые они получают.) Протестируйте для определенных типов только в случае необходимости. Это необходимо время от времени, поэтому Python дает вам type(), isinstance() и issubclass(), но будьте осторожны с ними.

Написание текста утилит Python эквивалентно "коду против интерфейса, а не объекту" в том смысле, что вам рекомендуется не заставлять ваш код слишком полагаться на тип объекта, а скорее на то, имеет ли он необходимый интерфейс, Разница в том, что в Python "интерфейс" означает неформальный набор атрибутов и методов объекта, которые обеспечивают определенное поведение, а не конструкцию языка, специально названную interface.

Вы можете формализовать "интерфейсы" Python до некоторой степени с помощью модуля abc, который позволяет объявить, что данный класс является подклассом данного "абстрактного базового класса" (интерфейса), используя любые критерии, которые вы желаете, такие как "он имеет атрибуты color, tail_length и quack, а quack - вызываемый". Но это все еще намного менее строго, чем статические языки, имеющие интерфейс.

Ответ 2

Чтобы понять интерфейсы в Python, вам нужно понять, как утка-типизация. С самого Python glossary:

duck-typing: стиль программирования, который не смотрит на тип объектов, чтобы определить, имеет ли он правильный интерфейс; вместо этого метод или атрибут просто вызывается или используется ( "Если он выглядит как утка и шарлатанцы, как утка, это должна быть утка".) Подчеркивая интерфейсы, а не конкретные типы, хорошо продуманный код улучшает его гибкость, позволяя полиморфное замещение. Утиная печать избегает тестов с использованием типов() или isinstance(). (Обратите внимание, однако, что утиная печать может быть дополнена абстрактными базовыми классами.) Вместо этого она обычно использует тесты hasattr() или EAFP.

Python поощряет кодирование интерфейсов, только они не применяются, но по соглашению. В Python очень распространены такие понятия, как итерации, вызовы или интерфейс файлов, а также встроенные функции, которые полагаются на такие интерфейсы, как map, filter или reduce.

Ответ 3

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

Например, (Java), у вас может быть интерфейс для симметричного шифрования:

public interface cipher 
{
    public void encrypt(byte[] block, byte[] key); 
    public void decrypt(byte[] block, byte[] key);    
}

Затем вы можете его реализовать:

public class aes128 implements cipher
{ 
    public void encrypt(byte[] block, byte[] key)
    {
        //...
    }
    public void decrypt(byte[] block, byte[] key)
    {
        //...
    }
}

Затем можно объявить объект следующим образом:

cipher c;

Что мы здесь сделали? Итак, мы создали этот объект c, тип которого должен соответствовать типу интерфейса. c может ссылаться на все, что соответствует этому интерфейсу, поэтому следующий этап:

c = new aes128();

Теперь вы можете вызывать методы, ожидающие наличия cipher.

Это java. Теперь вот что вы делаете в python:

class aes128(Object):

    def __init__(self):
        pass

    def encrypt(self, block, key):
        # here I am going to pass, but you really 
        # should check what you were passed, it could be 
        # anything. Don't forget, if you're a frog not a duck
        # not to quack!
        pass

Если вы хотите использовать это, и не уверены, что объект, которым вы были переданы, просто попробуйте его использовать:

c = aes128()
try:
    c.encrypt(someinput, someoutput)
except:
    print "eh? No encryption method?!"

Здесь вы полагаетесь на реализацию c.encrypt на raise, если он не может обработать то, что было передано, если метод существует. Конечно, если c является строковым типом и, следовательно, не нужного вам типа, он также автоматически запускается, и вы поймете (надеюсь).

Короче говоря, одна форма программирования набирается так, что вам нужно подчиняться правилам интерфейса, а другой говорит, что вам даже не нужно их записывать, вы просто верите, что если это не ошибка, это сработало.

Надеюсь, это покажет вам практическую разницу между ними.

Ответ 4

Что такое версия Python для "Код для интерфейса, а не для объекта"??

Правильная цитата - "программа против интерфейса, а не реализация". Принцип аналогичен принципу в Python, который он сделал в Smalltalk, языке, на котором он возник.

Имеет ли инструкция "Код против интерфейса, а не объект". имеют какое-либо значение в Python?

Да. Он имеет такое же значение в Python, как и в языке, на котором эта цитата исходила из (Smalltalk) и на любом другом языке.