Урлиб имеет много разных типов открывалок. Ну, ладно, у него есть пара, а не много, но это не относится к делу. Если вы вызываете urllib.open
так, как вы хотите, как должен урлиб знать, какой нож вы собираетесь использовать?
Он знает об этом, потому что ваш «промежуточный шаг» создал экземпляр определенного типа открывателя. Если вы создадите экземпляр FancyURLOpener
, python будет знать, что это особый тип открывателя, который вы хотите. Если вы хотите вместо этого использовать URLOpener
, создайте экземпляр , который, а затем вы можете использовать его вместо этого.
Не думайте об этом как о промежуточном шаге, думайте об этом как шаг - способ рассказать python «это конкретный тип открывателя url, который я хочу использовать».
Теперь, конечно, питон мог быть написан не-OO-способом, и если бы вы сказали открытому методу, какой тип открывателя вы хотели использовать. Например, способ, отличный от OO, мог бы сделать это: f = urllib.open({}, type="Fancy")
. Это может сработать, да? Многие люди пишут код в этом стиле, и он работает, так зачем беспокоиться об объектах?
Использование объектно-ориентированного метода означает, что вы можете создать свой собственный нож с его собственными специальными свойствами. Например, в документации для причудливой версии говорится, что «[предоставляет] обработку по умолчанию для следующих кодов ответов HTTP: 301, 302, 303, 307 и 401». Что делать, если вам также нужна обработка по умолчанию 404? Вы можете назвать это CJOpener, но для его использования вам придется самому изменить urllib
, чтобы взять «CJ», а также «Fancy» в качестве последнего параметра. Вы действительно хотите изменить встроенный код python?
Классы и объекты являются решением. Класс определяет интерфейс - стандартный способ, которым должен работать открыватель. Вы можете создавать свои собственные варианты, и все, что вам нужно сделать, это создать подкласс, а затем создать экземпляр этого подкласса. Как только вы это сделаете, любой код python в любой точке мира, который знает, как работать с FancyURLOpener
и URLOpener
, мгновенно знает, как работать с вашим открывателем.
Итак, преимущество этого промежуточного шага - удобный способ рассказать python о том, какой вариант использования обычного API вы хотите использовать. Все программы, которые знают, как использовать этот API, также будут знать, как использовать вашу версию API тоже (при условии, что вы не нарушите стандартный API).
Ответ Игнасио правильный, но для разработки «FancyURLopener» является * классом *, тогда как FancyURLopener ({}) 'является * экземпляром * класса. Метод 'open' работает только при вызове из экземпляра. В сообщении об ошибке говорится о том, что экземпляр является «первым аргументом», который немного запутан, но имеет смысл, если вы понимаете, что методы экземпляра определяются как «self» (текущий экземпляр) в качестве первого аргумента. – Fraxtil
Я не получил ваш ответ в первый раз, когда я прочитал его, но после прочтения, что ниже, это совершенно разумно. Спасибо! –