Лутц М. - Изучаем Python (1077325), страница 171
Текст из файла (страница 171)
веек(0); все вызовы метода геаб выполняют чтение из текущей позиции в файле, поэтому, чтобы начать повторное чтение, необходимо переместить текущую позицию в начало файла. Ниже показано, как может выглядеть такая реализация: бе( сспп1Ыпев((11е); Г!1е.веек(0) Ф Переместиться а начало файла ге!огп 1еп((11е.геас1ьпев()) Сет сспптСПагв(111е): Гт)е.веси(0) ге!игл 1еп(гт1е.геаб()) а то ке сансе(лереиаститься а начало) Свт !евт(папе); Г>1е = преп(паап) а Передать объект файла гетигп соил!(!пев(г!1в), сспшспагв(гт1е) Ф Открыть файл один раа »> !арсгт ауасб2 »> ауасб2. вавт("ауасз2.ру") (11 392) % рутвсп »> Ггса ауасб 1арсг! 2. (гоа)'г гоп *.
Ниже приводится решение в части использования инструкции вида (гоа *. Чтобы выполнить вторую часть упражнения, замените * именем сосп(СПагв: ВОб Решения упражнений »> сооп!Сяагв("ауаоб Ру") 291 3. аа1п . Если вы не допустили ошибок в модуле, он сможет работать в любом из режимов (в режиме самостоятельной программы или в режиме импортируемого модуля)." оеГ соил!(!пев(паве): (11е = орел(паве) ге!огп 1еп(г!)е.геа61!пев()) ое( сиоп!Свата(паве): ге!огп 1еп(орел(паве).геао()) оет сев!(паве)'. В Или передать объект Файла ге!огп соил!шпее(паве), сооп!с~ага(паве) в или вернуть словарь 1Г паве == ' аа!п ргъп! !ев!('ауаоб.ру') Я русвоп ауаоо,ру (13, 34б) 4.
Вложенное импортирование. Ниже представлено мое решение (файл тусйепг ру): Ггоа ауаоо гарог! сиоп!С!пев, соил!Сиате рг!п! соил!шпее('ауаоо,ру'), соил!спагв('ауаоо.ру') % ру!Поп аус11еп!.Ру 13 34б Что касается остальной части этого упражнения, функции модуля ауаоб доступны (то есть были импортированы) на верхнем уровне модуля аус1!епв, потому что инструкция угон просто присваивает их именам в импортирующем модуле (выглядит так, как если бы определения функций оеу находились в модуле аус1!еп!), Например, в следующем файле приводится альтернативный вариант реализации: !арог! аус1!еп! аус)!епг,соил!(!пев(...) Ггоа аус1ъеп! тарог! сооптСпагз соил!сиз!в(...) Если бы в модуле аус11еп! вместо инструкции т гон использовалась инструкция !арогс, вам пришлось бы использовать полные имена функций из модуля ауаоб: !прог! аус11еп! аус11еп!.ауаоо.сооп!(!лев(...) Ггоа аус1!еп! 1арог! ауаоо ауаоб.сооп!Спагв(...) Вообще говоря, можно определить модуль-коллектор, который будет импортировать все имена из других модулей, чтобы сделать их дос- Приложение В 806 тупными в виде единого модуля.
Если воспользоваться следующим программным кодом, вы покончите с тремя разными копиями имени зовепаве (воб1. еовепаве, со11есгаг. еовепаве и ва1п . аовепаве) — все три имени изначально будут ссылаться на один и тот же объект целого числа, а в интерактивной оболочке будет существовать только одно имя еовепаве: а файл. воб).ру вовепаве = 42 а файл: со11есгог.ру Ггов воб1 !врос! ° Ггов воб2 !прог! ° Ггов воб3 !фрог! * № Выборка всех пиен лереиенных № иэ инструкций присваивания и лреврвпение их № в собственные ииена этого иодуля »> Ггов со11есгог 1врог1 аовепаве б. Импорт пакетов.
Для атого упражнения я поместил файл тутси ру из упражнения 3 в каталог пакета. Далее описываются мои действия по настройке каталога и необходимого файла 1л11 .ру в консоли "тлг)пг)овгз — вы должны учитывать особенности своей платформы (например, использовать команды вч и ч! вместо вече и еб!!). Эти действия можно выполнять в любом произвольном каталоге (просто так вышло, что я запускал команды, находясь в каталоге, куда был установлен Руд)гоп), частично эти действия можно выполнить в проводнике файловой системы с графическим интерфейсом. По окончании я получил подкаталог тур)ву, содержащий файлы 1п11 гру и тутог(ру. В каталоге тур)га обязательно должен находиться файл 1л(б,ру, но его наличие в родительском каталоге необязательно. Каталог турйу находится в домашнем каталоге, в пути поиска модулей. Обратите внимание, что инструкция рг!п1 в иницнализационном файле выполняется только при первой операции импорта: С:>,ругпоп25> вкб1г вуркд С: 1Ру1лоп25> воче вувоб.ру вурадхвчвоб.ру с:>,Ругпоп25> еб11 вуркд~ 1п11 .Ру ...добавление инструкции рг!лг...
с;1Рутпоп25> ру1поп »> 1врогг зураб.вувоб 1и!11а1!г!пд вурКд »> вурйд.вувоб.сооп111пее('вурКд'>вувоб Ру ) 13 »> Ггов вурйд.вувоб 1врог1 соопгсаагв »> сопл!слега( ' вурхдхвувоб. Ру ' ) 345 6. Повторная загрузка. В этом упражнении вам просто предлагает поэкспериментировать с возможностью повторной загрузки модуля с)гапуегру из примера в книге, поэтому мне нечего показать здесь.
вот Решения упражнений 7. Циклический импорт. Суть в том, что, когда первым импортируется модуль гесс г2, ситуация рекурсивного импорта возникает в инструкции [прог( в модуле гессг1, а не в инструкции (гса в модуле гессг2. Если говорить более подробно, все происходит следующим образом: когда модуль гесс г2 импортируется первым, в результате рекурсивного импорта модуля гесс г2 из модуля гесс г1 модуль гесс г2 извлекается целиком. К моменту, когда модуль гесс г2 импортируется модулем гесс г1, его пространство имен еще не заполнено, но так как импортирование выполняется инструкцией 1арсг(, а не инструкцией ггса, никаких проблем не возникает: интерпретатор отыскивает и возвращает уже созданный объект модуля гесиг2 и продолжает выполнять оставшуюся часть модуля гесс г1 без сбоев. Когда импорт в модуле гесс г2 возобновляется, вторая инструкция (гсв обнаруживает в модуле гесиг1 имя у [модуль был выполнен полностью), поэтому в такой ситуации не возникает ошибок.
Запуск файла как отдельного сценария — это не то же самое, что импортирование его в виде модуля: это равноценно интерактивному выполнению первой инструкции [прог( или ггсв в сценарии. Например, запуск модуля гесиг1 как сценария равносилен предварительному импортированию модуля гессг2 в интерактивной оболочке, поскольку гессг2— это первый модуль, импортируемый в гесиг1. Часть Ч1.
Классы и ООП Упражнения находятся в главе 26, в разделе «Упражнения к шестой части«. 1. Наследование. Ниже приводится решение этого упражнения [файл аЮегру) вместе с несколькими примерами действий в интерактивной оболочке. Метод перегрузки оператора аоо присутствует только в суперклассе и вызывает конкретные методы воз, определяемые подклассами: с1ввв АССег: Се( взд(вв1(, х, у)' рып( 'по( 1вр1еившез' ' пег шы (ве1(, в(вгг=[]): вв)(.ав(в = в(вг( Св( вСС (вв)Г, с(Пег): и Или в ппдклассахт гвтпгп вв1( всщвв!г,св1в, огпвг) и или воэвравать тип« с1ввв [1в(АССег(АССег): Св( аСС(ве1(, х, у); гвтпгп х « у с1ввв Стс(пазег(АССег).
Св( ввв(ве!Г, х, у); пви = () гог и кп х.хеув(): яви[к] = х[х] гог и 1п у.хеув(): пви[к] = у[х] Приложение В ге(огп пви й рувлоп »> Тгоа забег 1арогт ° »> х = Аббег() »> х,абб(1, 2) пот тер1ееепТеб' »> х = [1ввдабег() »> х.абб([1], [23) [1, 2] »> х = р(свдбаег() »> х. ааа((1: П, (2: 2) ) (1. 1, 2: 2) »> х Аббат([1]) »> х+ [23 пег 1ар1еаепгеб! »> »> х = [1звдааег([1]) »> х+ [2] [1. 2] »> [23+х тгасеоасх (1ппегаовг 1авг): е1|е т<згатп>", 11пе 1, тп ? ТуреЕггог абб пот гаса бетюеб Тог гневе орегапбв (ТуреЕггог.
ни абб , ни габб не определен для этих операндов) Обратите внимание, что в последнем тесте возникла ошибка при попытке использовать экземпляр класса справа от оператора «. Если вы захотите исправить эту ошибку, реализуйте метод габб, как описывается в главе 24, в разделе «Перегрузка операторов». Если вы начнете сохранять текущее значение в экземпляре, вы можете также переписать метод аба, чтобы он принимал единственный аргумент, в духе других примеров из шестой части: с1авв Аабег аег юы (ве1(, втагг=[3): зе!г аага = втагт ае( абб (ве1(, отлет) № Пвредлется единственный аргумент гетсгп ве1( ааа(отлет) № Операнд слева хранится в ве1 Г ает ааа(ве11, у) ргтпт 'по1 тир1елелтетд ' с1авв [тзтяббег(Абаег) бет абб(ве!Г, у): ге1огп зе1(.аа1а » у с1авз 0>сслббег(Аааег): аег ааа(зе)Т, у); раза № измените, чтобы испол»зоват» ве)г.бага вместо х х = ЫВТАаавг([1, 2,3]) у = х » [4, 5.
63 ргтп1 у № Выведет [1, 2, В, 4, 5, В] Решения упражнений 809 Поскольку значения присоединяются к самим объектам, а не передаются в виде аргументов, эта версия определенно является более объектно-ориентированной. И как только вы доберетесь до этого момента, вы наверняка обнаружите, что вообще можно избавиться от методов абб и просто определить методы абб в двух подклассах. 2. Перегрузка оператороз. В программном коде решения (файл тур [вару) используется несколько методов перегрузки операторов, о которых в книге рассказывается не слишком много, однако в них нет ничего сложного.
Операция копирования начального значения в конструкторе имеет большое значение, потому что оно может быть представлено изменяемым объектом — едва ли есть разумная причина, чтобы изменять или обладать ссылкой на объект, который, вполне возможно, используется где-то за пределами класса. Метод десассг перехватывает попытки обращения к обернутому списку. Подсказки, которые помогут упростить реализацию, вы найдете в разделе «Расширение типов наследованием» в главе 26: с1авв иуссвс бег спсс (ве1(, всагс). аве1(.игарреб = втагс[.] г скопироеате вгагс: г беэ побочных эФФектое ве1(.ыгарреб = [] г убедит»си, что это список Гог х сп всагс: ве1(.игарреб.аррепб(х) бес абб (ве1(, ответ); гесогп муывс(ве1(.игарреб + оспег) бег ао1 (ве1Г, Стае): гесогп иуссвс(ве1г.ыгарреб ° стае) бет деСстеа (ве1(, отсвет): гесогп ве)г.игарреб[о(свес] бе( 1еп (ве1Г): гетнгп 1еп(ве1(.нгарреб) бес цесв1ссе (ве1(, 1ои, псцп): ге(ого мус1вс(ве1(.ыгарреб[1ои псцп]) бег аррепб(ве1(, побе): ве1(.ыгарреб.аррепб(позе) бег цесассг (ве1(, папе): г другие члены: эогсг'геуегве/и т, д.
гесогп десассг(ве1(.нгарреб, пап|е) бег герт (ве1Г): гесогп герт(ве1(.ыгарреб) сс паве == ' аасп х = Иу(свг( врь, ) ргспС х ргпп х[2] ргст х[1: ) ргспс х + ['едцв'] ргспт х * 3 х.аррепб('а') х вогс() ГОг С сп х, Ргспт с, 810 Приложение В % рузаоп ау1!з!.Ру [ 5, Р, а, а ] а ['р', 'а', 'а'] ['з', 'Р', 'а', 'а', 'е995'] ['з', 'р', 'а', 'а', 'з', 'р', 'а', 'а', 'в', 'р', 'а', 'а'] а а а р з Обратите внимание, насколько важно копировать начальное значение, выполняя добавление в конец вместо извлечения среза, потому что в противном случае может получиться объект, не являющийся списком и потому не обладающий методами списка, такими как арреп() (например, операция извлечения среза строки возвращает другую строку, но не список).
Если бы начальное значение было объектом типа Му[!51, можно было бы выполнить копирование с помощью операции извлечения среза, потому что этот класс перегружает эту операцию и обеспечивает ожидаемый интерфейс списков. Однако для других объектов, таких как строки, следует избегать использования операции извлечения среза. Кроме того, следует заметить, что на сегодняшний день тип множества стал встроенным типом в языке Ру(]топ, поэтому цель данного упражнения в значительной степени заключается в том, чтобы просто дать возможность попрактиковаться (подробнее о множествах рассказывается в главе 5).
3. Подклассы. Мое решение (файл тузи[ьру) приводится ниже. Ваше решение должно быть похожим: Ггоа ау155! !прог! Му(!ж с)азз Му(тз!Ввь(ау(тз!): са115 = 0 В Используется всеми экземплярами оег тпт! (зе)П з!аг!): зе)т.авсз = 9 В Свой для каждого экземпляра Му(!з! шт! (зе1П зтаг!) оет аоо (зеы, о!Ьег): МуЬш!Воь.са115 = МуЬ!з!Вво.са115 + 1 в Счетчик, единый для класса зе1(.аооз = зеи .асов в 1 В Подсчет экземпляров гетогп муь!51, аво (зе1П о!Ьег) Оет з!атз(зе)Г): ге!огп зе1(.55115, ЗЕ1(.аовз В А11 асса, ау аооз Ы папе == ' аазп х = Му(15(ВОЬ( зраа ) Му(тзтзвЬ( (оо ) ргтп! х[2] рг1п! х[ 1: ] рггп! х ж ['е995'] рып! х в ['тоаз! ] ргтпт у + ['Ьаг'] ргтп! х жатв() Решения упражнений % руваоп вузцЬ,ру в ['р', 'в', 'щ'] ['з', 'р', 'а', 'ю', 'еддз'] ['з', 'р', 'а', 'в', Повзт'] ['Г', 'о', 'о', 'Ьвг'] (3, 2) 4.