Общие вопросы
Подписаться на эту рубрику по RSS
Функции являются отличным помощником во всех языках программирования. Они способствуют улучшению кода за счет выполнения ими повторных задании без нужны дублировать код для получения результата без использования функции. Код функции должен быть как можно более компактнее. Функция должна выполнять только одну операцию. Она должна выполнять ее хорошо и ничего другого она делать не должна. Чтобы создать читабельный код для вам и для других программистов вы должны следить за ним. Вы работаете с с чистым кодом, если каждая функция в основном делает то, что вы от нее ожидали. Половина усилий по реализации этого принципа сводится к выбору хороших имен для компактных функции, выполняющих одну операцию.
Чем меньше и специализированнее код функции, тем проще выбрать для нее понятное имя. Не бойтесь использовать длинные имена. Длинное содержательное имя лучше короткого невразумительного. Будьте последовательны в выборе имени. Используйте в имени функции те же словосочетания, глаголы и существительные, которые используются в ваших модулях. Создание функции производится с помощью инструкции def, как показано в следующем примере. Мы уже научились работать со списками в python, давайте воспользуется знаниями тут.
# -*- coding: utf-8 -*- Phones = ['Nokia', 'Samsung', 'LG', 'Sony'] def show_as_text(user_list): words = '' for value in user_list: words += str(value) + ' ' return words print 'Phones: ', show_as_text(Phones) # Вернет: Phones: Nokia Samsung LG SonyДалее...
В чем же заключается великолепие чехла для ноутбука MacBook? Выбирая чехол для защиты Вашего MacBook Pro 13 необходимо точно знать структуру чехла.
Основой замечательного чехла для ноутбука считается отличный дизайн. Дизайн чехла, который обеспечивает не только доступ и функциональность, но также предоставляет блестящий вид и гармоничность. Дизайн, который не отвлекает, а наоборот, увеличивает привлекательность ноутбука. Чехол должен быть тонким, не громоздким и легким для лучшей портативности. Отличный чехол - это такой чехол, который обеспечивает удобное пользования ноутбуком MacBook Pro 13 в дороге, и при этом гарантирует удобство использования всех функций ноутбука в любом положении.
Замечательным чехлом можно назвать тот, который надежно защищает Ваш компьютер от царапин и вмятин, а также тот, который можно закрыть и надежно закрепить. Структура отличного чехла дает Вам возможность работать с ноутбуком в самых ограниченных пространствах, ибо компактный чехол с легкостью позволяет начать работу, где бы Вы не были. Благодаря правильному теплообмену, отличный чехол охлаждает ноутбук и обеспечивает хорошую функциональность.
Модуль datetime предоставляет классы для обработки времени и даты разными способами. Поддерживается и стандартный способ представления времени, однако больший упор сделан на простоту манипулирования датой, временем и их частями.
Классы, предоставляемые модулем datetime:
Класс datetime.date(year, month, day) — стандартная дата. Атрибуты: year, month, day. Неизменяемый объект.
Класс datetime.time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None) — стандартное время, не зависит от даты. Атрибуты: hour, minute, second, microsecond, tzinfo.Далее...
Одним из важных моментов при использовании потоков является избежание конфликтов доступа, когда более одному потоку требуется доступ к переменной или какому-либо ресурсу. Если не проявить осторожность, одновременный доступ и модификация из нескольких потоков может вызвать всевозможные проблемы, и, что ещё хуже, эти проблемы имеют свойство проявляться лишь под большой нагрузкой, или на продакшн-серверах, или на более быстром железе, которое используют ваши клиенты. (Сейчас более-менее устоялось название "heisenbugs" для трудновоспроизводимых багов - прим. перев.)
Для примера представьте программу на Python, обрабатывающую какие-нибудь данные и отслеживающую, сколько элементов было обработано:
counter = 0 def process_item(item): global counter ... do something with item ... counter += 1
Если вызывать эту функцию из более чем одного потока, можно обнаружить, что счетчик counter не обязательно точен. Код будет работать верно в большинстве случаев, но иногда пропускать один или несколько элементов. Причина в том, что операция сложения на самом деле выполняется в три шага: интерпретатор получает текущее значение счетчика, вычисляет новое значение, и наконец, записывает его в переменную.
Если другой поток получает управление в тот момент, когда текущий поток получил значение переменной, он может выполнить вышеописанные 3 шага до того, как их выполнит текущий поток. А так как оба потока получили одно и то же начальное значение переменной, то переменная будет увеличена лишь на 1.
Другая распространённая проблема заключается в возникновении объектов в неполном или неконсистентном состоянии. Объект в таком состоянии может возникнуть, когда поток, производящий инициализацию или обновление сложной структуры данных прерывается другим потоком, который пытается эту структуру использовать во время обновления или инициализации.
Атомарные операции
Простейший способ синхронизировать доступ к разделяемым данным или ресурсам - положиться на атомарные операции в интерпретаторе. Атомарная операция - операция, выполняемая за 1 шаг, без возможности прерывания её другим потоком.
В целом, этот подход работает только если разделяемый ресурс состоит из единственного экземпляра встроенного типа, например, строки, числа, списка или словаря. Вот некоторые потокобезопасные операции:
Программирование Web-клиента - мощная техника для создания запросов в Web. Web-клиент - это любая программа, извлекающая данные с Web-сервера при помощи протокола передачи гипертекста (Hyper Text Transfer Protocol, http в ваших URL). Web-броузер является клиентом, так же, как и поисковики, то есть программы, автоматически перемещающиеся по Web для сбора информации. Вы можете также применять Web-клиенты для использования возможностей сервисов, предлагаемых другими обитателями Web, и добавления динамических свойств в ваш собственный Web-сайт.
Программирование Web-клиента входит в любой набор инструментов для разработчиков. Приверженцы Perl'а используют его многие годы. В языке Python этот процесс достигает даже более высоких уровней удобства и гибкости. Большинство необходимых вам функций обеспечивается тремя модулями: HTTPLIB, URLLIB и новым дополнением, XMLRPCLIB. В истинно Питоновском стиле каждый модуль надстроен над своим предшественником, обеспечивая таким образом прочную, хорошо спроектированную базу для ваших приложений. В этой статье мы рассмотрим первые два модуля, оставив XMLRPCLIB на потом.
Для наших примеров мы будем использовать Meerkat. Если вы похожи на меня, вы тратите время на отслеживание тенденций и событий в среде создателей открытых программных средств, которые позволят вам получить конкурентные преимущества. Meerkat представляет собой инструмент, значительно упрощающий эту задачу. Это служба открытого доступа (an open wire service), собирающая и упорядочивающая огромные объемы информации по открытым программным средствам. Поскольку его интерфейс для браузера гибок и настраиваем, то, используя программирование web-клиента, мы можем сканировать, извлекать и даже сохранять эту информацию для последующего использования в автономном режиме. Сначала мы обратимся к Meerkat с помощью HTTPLIB в интерактивном режиме, а затем перейдем к работе с Meerkat's Open API через URLLIB, чтобы создать настраиваемое средство сбора информации.
Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход. Python поддерживает множественное наследование, переопределение инфиксных операторов, причем можно переопределить операцию как для левого операнда, так и для правого; в версии 2.1 есть полное переопределение операторов сравнения (механизм rich comparison для объектов, поддерживающих частичное упорядочивание, например, матриц).
В Python имеются исключения и механизм их перехвата; таким образом программист может построить правильную обработку ошибок и создать надежную программу. Встроенные механизмы интроспекции позволяют опрашивать интерфейсы объектов во время выполнения программы. Например, можно узнать количество и имена параметров функции; эту интроспекцию использует Zope, чтобы подготовить правильный список параметров функции при вызове ее из web.
Из современных языков Python можно сравнить в первую очередь с Java и Perl. Python выполняет все обещания, которые дала, но не выполнила Java. Python очень хорошо переносим. Он работает на всех платформах, на которых есть Java, и еще на многих. Мало найдется таких платформ, на которые Python не перенесен. Я не говорю про UNIX и Windows, конечно - с точки зрения переносимости куда интереснее такие платформы как Mac, Amiga, Palm, RiscOS, AS/400 и многие другие. Для особых любителей Java есть Jython. Он состоит из двух частей: во-первых, это интерпретатор Pyhon, написанный на Java, а во-вторых это компилятор Python в байт-код Java. В сравнении с Perl - Python как язык ему совершенно равномощен, но избавлен от великого множества неприятностей и неудобств, присущих Perl. Python обладает богатой стандартной библиотекой, плюс великим множеством модулей, доступных в Интернете. Для пользователей Windows есть пакет win32, из которого доступны практически все функции Windows API, DDE, COM.
При сборе статистики посещения web-страниц часто собирается информация о количестве посетителей из разных стран. Как правило, страну определяют по домену первого уровня. Но такая информация не всегда соответствует действительности, особенное учитывая нынешнюю тендецию использовать национальные домены co, tv не по назначению. Кроме того, как быть с доменами общего пользования net, org, com и др.? С IP-адресами, для которых нет записей в реверсной зоне? Ну и, наконец, определение доменного имени отнимает заметное количество времени.
Приведенный в статье код распространяется под лицензией в стиле Python, то есть может быть использован для любых (в том числе коммерческих целей) при условии сохранения замечания об авторском праве Copyright © 2002, Denis S. Otkidach
Данные о регистрации диаппазонов IP-адресов хранятся в базах данных whois. Чтобы предоставить возможность общественности анализировать трафик, RIPE NCC, ARIN и APNIC не реже, чем раз в месяц, делают сокращенные "снимки" своих баз данных. Именно из этих данных мы и составим локальную базу.
Но сначала нужно эффективно оргазовать хранение данных для диаппазонов IP-адресов, чтобы обеспечить к ним быстрый доступ. За основу возмем BTree базу BerkleyDB, доступ к которой обеспечивает функция btopen() из стандартного модуля bsddb. В качестве ключей будем использовать начало диаппазона IP-адресов, а в качестве значений — его конец и дополнительную информацию. Ключи и значения в bsddb должны быть строками. Кроме того, необходимо обеспечить упорядоченность ключей. Для этого очень хорошо подходит функции inet_aton и inet_ntoa из модуля socket.
В своей работе я использую PyCharm — отличную среду разработки, которая много всего умеет, упрощает рутину(чем сильно повышает продуктивность разработчика) и вообще не заменима для Django-devелоперов.
В настоящий момент я работаю над проектом, который по ряду причин, не могу запустить на своей машине. Обновленный код приходится закачивать на сервер, перезапускать проект и только тогда я увижу как оно работает. Терять в удобстве разработки и отладки мне не хотелось. Поэтому пришел к использованию следующей связки инстурментов:
- На рабочей машине(Mac) разрабатываю под PyCharm
- В PyCharm как правило постоянно включена удаленная отладка.
- Для работы удаленной отладки в код проекта, необходимо внести 2 строки кода для запуска отладки и положить 1 файл, доступный в python-path.
- После внесения изменений в код, я на рабочей машине запускаю скрипт, который закачиваюет изменения на сервер с помощью rsync и перезагружает сервер проекта.
Про настройку удаленной отладки в PyCharm
В директорию проекта нужно положить файл из директории PyCharm под названием: pycharm-debug.egg. В Django-проекте я нахожу то место, которое мне нужно отладить и в начале отлаживамого def’а(например) ставлю следующий код:
sys.path.append(‘/home/webmail/src/pycharm-debug.egg’) from pydev import pydevd pydevd.settrace(’213.180.204.11′, port=32456, stdoutToServer=True, stderrToServer=True)IP адрес и порт – это те по которым внешний сервер будет стучаться для того, чтобы найти запущенный PyCharm, которому он выдаваст отладочную информацию. Адрес Необходимо, настроить NAT, чтобы такие запросы попадали на машину разработчика.
Так как я на сервере не использую Django Development Server, а вместо него — nginx+uwsgi, то в параметрах запуска uwsgi я указал 1 процесс. Иначе будут сложности с отладкой, из-за нескольких попыток подключиться к моему компьютеру.
Важно! Для удаленной отладки исходные коды должны быть идентичны на локальном и удаленном сервере, в противном случае, может проявиться странное поведение дебаггера.
Первые пол дня я использовал CyberDuck для закачивания обновленных файлов на сервер. Но мне это быстро надоело. И родилось решение, котором расскажет следующая часть этой статьи: про rsync.
Поднятие объектно-ориентированного программирования на новый уровень
Большинство читателей уже знакомо с концепциями объектно-ориентированного программирования: наследованием, инкапсуляцией, полиморфизмом. Но создание объектов заданного класса с определенными родителями обычно представляется исходно заданной операцией. Оказывается, что ряд новых программных конструкций становится либо более простым, либо вообще хоть сколько-нибудь возможным, если вы можете настраивать процесс создания объектов. Метаклассы разрешают определенные типы "аспектно-ориентированного программирования"; например, можно усилить классы такими характеристиками, как возможности трассировки, объектная персистентность, регистрация исключений и так далее.
Краткий обзор объектно-ориентированного программирования (ООП)
Давайте, потратив полминуты, вспомним, что такое ООП. В языке объектно-ориентированного программирования можно определять классы, задача которых - объединить связанные данные и поведение. Эти классы могут наследовать некоторые или все свойства своих родителей, они также определяют свои собственные атрибуты (данные) или методы (поведение). В результате, классы, как правило, выступают в качестве шаблонов для создания экземпляров (которые время от времени называют просто объектами). Различные экземпляры одного и того же класса обычно имеют разные данные, хотя они будут представлены в одинаковом виде, например, у обоих объектов класса 'Employee' bob и jane есть .salary и .room_number, но значения room (комната) и salary (жалование) у каждого различны.
Яндекс.ДиректВсе объявленияЯ хочу лучше фотографировать! Запишись на бесплатный онлайн-семинар по фотографии и секретам мастерства! webinar.disted.ru
Некоторые объектно-ориентированные языки программирования, включая Python, предусматривают интроспективные (или рефлексивные) объекты. Другими словами, интроспективный объект может сам себя описывать: к какому классу принадлежит этот экземпляр? Кто предки этого класса? Какие методы и атрибуты доступны объекту? Интроспекция позволяет функции или методу, управляющему объектами, принимать решения, основываясь на том, какой вид объекта передается. Даже без интроспекции функции часто ветвятся, опираясь на данные экземпляра - например, маршрут к jane.room_number отличается от пути к bob.room_number, поскольку они в "различных комнатах" (значения room у них различны). С помощью интроспекции также можно безошибочно вычислить bonus (премиальные) jane, пропустив это вычисление для bob, например, потому что у jane есть атрибут .profit_share или из-за того, что bob является экземпляром производного класса Hourly(Employee).
"Метапрограммный" ответ
Базовая система ООП, очерченная выше, является достаточно мощной. Однако, в этом описании один момент не получил должного внимания: в Python (и других языках) сами классы являются объектами, которые можно передавать и подвергать интроспекции. Но поскольку объекты, как отмечалось, создаются с использованием классов в качестве шаблонов, то что же является шаблоном для создания классов? Разумеется, метаклассы.
В Python всегда были метаклассы. Однако, технология, задействованная в метаклассах, стала гораздо более очевидной с выходом Python 2.2. А именно, в версии 2.2 Python перестал быть языком только с одним специальным (обычно невидимым) метаклассом, который создавал каждый объект класса. Теперь программисты могут наследоваться от встроенного метакласса type и даже динамически генерировать классы с различными метаклассами. Разумеется, только то, что вы можете манипулировать метаклассами на Python 2.2, еще не объясняет, зачем вам это.
Более того, вам не нужно использовать метаклассы, определенные пользователем, чтобы управлять созданием классов. Несколько менее головоломная концепция - фабрика классов (class factory): обыкновенная функция может возвращать класс, который был динамически создан в пределах тела функции. В традиционном синтаксисе Python вы можете написать: Далее...
К изменяемым объектам в Python относятся списки, словари и объекты наследуемые от базового класса object. Будьте крайне внимательны при написании программ, помните что связь на изменяемый объект сохраняется всегда.
class M(object): def __init__(self, data): self.__data = data def data(self): return self.__data init_data = ['php'] m = M(init_data) print m.data() # ['php'] init_data.append('python') # объекты init_data и M.__data ссылаются на один и тот же объект print init_data # ['php', 'python'] print m.data() # ['php', 'python'] data = m.data() print data # ['php', 'python'] data.append('ruby') # теперь уже 3 объекта ссылаются на одну и ту же переменную print data # ['php', 'python', 'ruby'] print init_data # ['php', 'python', 'ruby'] print m.data() # ['php', 'python', 'ruby']
На самом деле даже если вы отправляете объект в функцию, связь не теряется на выходе. Функция возвращает ссылку на переменную.
M = lambda data: data init_data = ['php'] m = M(init_data) m.append('python') print m # ['php', 'python'] print init_data # ['php', 'python'] print m is init_data # True
Будьте внимательны при написании программ, иногда необходимо чтобы метод класса или функция вернули новый объект, а не ссылку. Создать новый объект например из списка можно - list(lst), из словаря dict(). В остальных случаях поможет модуль copy.Далее...