Django — Python. Как сложить две переменные со значением времени


Содержание

Как отображать текущее время с помощью Python + Django?

Я изучаю, как использовать Python и Django для создания небольшого webapp, который выводит текущее время. Я использую это с Google App Engine.

Сейчас он отображает только пустую страницу, но я хочу, чтобы она отображала текущее время. Я также хочу отобразить функцию на домашней странице. Not/time/.

Возможно, эта документация вам полезна: Часовой пояс

Время форматирования в представлении

Вы можете получить текущее время, используя:

или для получения времени в зависимости от часового пояса:

, чтобы отформатировать время, которое вы можете сделать:

Время форматирования в шаблоне

Вы можете отправить дату-время в шаблон, допустив, что вы отправляете переменную с именем myDate в шаблон из представления. Вы можете сделать это так, чтобы форматировать это datetime:

Django — Python. Как сложить две переменные со значением времени?

Переменная в языке программирования это название для зарезервированного места в памяти компьютера, предназначенное для хранения значений. Это означает, что когда вы создаете переменную, вы на самом деле резервируете определенное место в памяти компьютера.

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

Для понимания, можете думать о переменной как о коробке, в которую можно положить любую вещь, но только определенного размера. Размер в данном примере будет типом переменной. Это не совсем верное определение, но оно дает общее представление о картине в целом.

Присвоение значения переменной:

В Python вам не нужно объявлять тип переменной вручную (как, например в С++). Объявление происходит автоматически (это называется динамическая типизация), когда вы присваиваете значение переменной. Знак равенства ( = ) используется для присвоения значения переменной.

Операнд по левую сторону от знака равно ( = ) это имя переменной, операнд по правую сторону — значение присвоенное этой переменной.

При выполнении, данный код выведет:

Множественное присвоение значений:

В Python возможно присваивать одно значение нескольким переменным сразу. Например:

В данном создается объект со значением 1, и все 3 переменные указывают на область в памяти, в которой он находится.

Встроенные типы данных в Python:

Информация, сохраненная в памяти может быть разных типов данных. Например, возраст человека может быть числовым значением, а его адрес — буквенно-числовым. В Python существует множество стандартных типов данных, которые используются для хранения определенных значений и обладают своими специфическими методами.

К стандартным типам данных в Python относят:

Числовой тип данных в Python:

Числовой тип данных в Python предназначен для хранения числовых значений. Это неизменяемый тип данных, что означает, что изменение значения числового типа данных приведет к созданию нового объекта в памяти (и удалению старого)

Числовые объекты создаются, когда вы присваиваете им значение. Например:

Также вы можете удалять числовой объект при помощи ключевого слова del. Синтаксис команды del следующий:

В Python есть четыре вида числового типа данных:

  • int (целое число)
  • long (длинное целое число [может быть представлено в восьмеричной или шестнадцатеричной системе исчисления])
  • float (число с плавающей точкой: -0.2, 0.0, 3.14159265 и т.д.)
  • complex (комплексное число)

Примеры видов числового типа данных:

int long float complex
1 51924361L 0.0 3.14j
102 -0x19323L 15.20 45.j
-786 0122L -21.9 9.322e-36j
0xDEFABCECBDAECBFBAEl 32.3+e18 .876j
0b10 535633629843L -90. -.6545+0J
-0x260 -052318172735L -32.54e100 3e+26J
0x69 -4721885298529L 70.2-E12 4.53e-7j

Строки в Python:

Под строками в Python подразумевается набор символов между кавычками. В Python можно использовать пары одинарных либо двойных кавычек. Из строк можно взять подстроку используя оператор нарезки ( [ ] и [ : ] ) с индексами от нуля для первого символа строки и до последнего. Так же можно использовать обратную индексацию от -1 для последнего символа до начала.

Оператор плюс ( + ) для строк соединяет две строки в одну, звездочка ( * ) оператор повторения. Например:

В результате вы увидите следующее

Списки в Python:

Списки, пожалуй, самый универсальный составной тип данных в Python. Список состоит из элементов, разделенных запятыми, находящихся между квадратными скобками ( [ ] ). В определенной мере, списки подобны массивам в C. Единственной разницей является то, что элементы одного списка могут иметь разные типы данных.

Получить доступ к элементам, сохраненным в списке можно, точно так же, как и в строках, при помощи оператора нарезки ( [ ] и [:] ) и индексов, начиная с нуля и до конца. Знак плюс ( + ) объединяет два списка, а звездочка ( * ) — оператор повторения для списка. Например:

В результате вы увидите :

Кортежи в Python:

Кортеж это еще один составной тип данных, похожий на список. Кортеж состоит из ряда значений, разделенных запятыми, заключенными в круглые скобки ( ( ) ). Основным различием между списками и кортежами является то, что элементы кортежей не могут быть изменены. То есть, кортежи можно рассматривать как списки доступные только для чтения.

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

В результате вы получите:

При этом, следующие действия доступны для списков и недоступны для кортежей:

Словари в Python:

Словари в Python это неотсортированная колекция элементов, доступ к которым осуществляется по ключу. То есть, каждому ключу словаря соответствует определенное значение. Ключом может быть любой неизменяемый тип данных (число, строка, кортеж), значением — любой тип данных.

Пары ключ, значение словаря заключаются в фигурные скобки ( < >). Есть несколько способов создания словарей:

Данный код выведет следующее:

Обратите внимание, что ключи и значения выводятся не в том порядке, в котором мы их задавали.

Сеты в Python:

Сет в Python это еще один изменяемый, коллекционный тип данных, отличительной чертой которого является то, что он хранит только уникальные значания.

Создать сеты можно следующими способами:

Для добавление элемента в сет используется метод add, для удаления — pop или remove. Добавление в сет уже существующего элемента не повлияет на сет. Сеты обладают множеством методов для работы с уникальными элементами, например difference — возвращает элементы сета отсутствующие в другом сете, intersection — наоборот, возвращает елементы сета присутствующие в другом сете.

Преобразование типов данных:

Иногда может возникнуть необходимость преобразовать один тип данных в другой. Для этого существуют специальные встроенные функции Python. Вот некоторые из них:

Преобразовывает х в целое число. Например, int(12.4) -> 12

Преобразовывает х в long. Например, long(20) -> 20L

Преобразовывает х в число с плавающей точкой. Например float(10) -> 10.0

Создает комплексное число. Например complex(20) -> (20+0j)

Преобразовывает х в строку. Например str(10) -> ’10’

Преобразовывает s в кортеж. Например tuple(«hello») -> ( «h»,»e»,»l»,»l»,»o» )

Преобразовывает s в список. Например list(«Python») -> [ «P»,»y»,»t»,»h»,»o»,»n» ]

Создает словарь из d. Например dict( [ (1,2), (3,4) ] ) ->

Как к нынешней дате добавить 30 минут?

Нужно взять дату и время, и добавить к времени 30 минут. Как вывести дату и время знаю, но вот никак не получаеться добавить 30 минут:

2 ответа 2

Чтобы получить datetime значение, соответствующее половине оборота минутной стрелки (30 минут по часам) от текущего значения:

Если вы хотите получить локальное время, которое будет через 1800 секунд от текущего в будущее, то это значение может отличаться из-за перевода часов (к примеру, из-за разницы между летним/зимним временем в текущей часовой зоне). В этом случае следует использовать datetime с tzinfo (Питон 3):

python на текущей платформе может не иметь доступа к tz database (Windows) или на старых Питон версиях нет timezone модуля. Самый переносимый вариант это использовать информацию о часовых поясах из pytz модуля:

tzlocal модуль используется, чтобы найти pytz временну́ю зону, соответствующую локальной часовой зоне.

pendulum позволяет скрыть эти детали, связанные со сменой смещения от UTC в местном времени:

Если вы не знали, что местное время может повторяться (не монотонно, не уникально) или вообще отсутствовать, посмотрите на картинки в python converting string in localtime to UTC epoch timestamp.

Часто задаваемые вопросы

Некоторые не совсем очевидные вещи, с которыми сталкиваются начинающие программисты Python.

Почему я получаю исключение UnboundLocalError, хотя переменная имеет значение?

Может показаться неожиданным получить UnboundLocalError в ранее работающем коде, в который добавили операцию присваивания где-то внутри функции.

работает, но следующий код:

приводит к UnboundLocalError:

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


Когда последняя инструкция в foo присваивает новое значение переменной x, компилятор решает, что это локальная переменная. Следовательно, когда более ранний print пытается напечатать неинициализированную переменную, возникает ошибка.

В примере выше можно получить доступ к переменной, объявив её глобальной:

Это явное объявление требуется для того, чтобы напомнить вам, что (в отличие от внешне аналогичной ситуации с переменными класса и экземпляра), вы на самом деле, изменяете значение переменной во внешней области видимости:

Вы можете сделать подобную вещь во вложенной области видимости использованием ключевого слова nonlocal:

Каковы правила для глобальных и локальных переменных в Python?

В Python, переменные, на которые только ссылаются внутри функции, считаются глобальными. Если переменной присваивается новое значение где-либо в теле функции, считается, что она локальная, и, если вам нужно, то нужно явно указывать её глобальной.

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

Почему анонимные функции (lambda), определенные в цикле с разными значениями, возвращают один и тот же результат?

Например, вы написали следующий код:

Это даёт вам список из 5 функций, считающих x**2 . Можно ожидать, что, будучи вызванными, они вернут, соответственно, 0, 1, 4, 9, и 16. Однако, вы увидите, что все они возвращают 16:

Это случается, поскольку x не является локальной для lambda, а определена во внешней области видимости, и получается тогда, когда она вызывается — а не когда определяется.

В конце цикла, x=4, поэтому все функции возвращают 4**2 , то есть 16. Это можно также проверить, изменив значение x и посмотрев на результат:

Чтобы избежать подобного, необходимо сохранять значения переменных локально:

Здесь, n=x создаёт локальную для функции переменную n и вычисляется в момент определения функции:

Как организовать совместный доступ к глобальным переменным для нескольких модулей?

Канонический способ организовать подобный доступ — это создать отдельный модуль (часто называемый config или cfg). Просто добавьте import config в каждый модуль приложения. При этом модуль становится доступен через глобальное имя. Поскольку существует только один экземпляр модуля, любые изменения, произведённые в модуле отражаются везде. Например:

По тем же соображениям, модули можно использовать как основу для имплементации синглтона.

Как правильнее использовать импортирование?

В общих случаях не используйте from modulename import *. Это засоряет пространство имён того, кто импортирует. Некоторые люди избегают этой идиомы даже для тех немногих модулей, которые были спроектированны, чтобы так импортироваться. Это такие модули как Tkinter и threading.

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

Хорошая практика, если Вы импортируете модули в следующем порядке:

  • стандартные библиотечные модули (например, sys, os, getopt, re)
  • модули сторонних разработчиков (всё, что установлено в директории site-packages) — например, PIL, NumPy и т.д.
  • локально созданные модули

Иногда бывает необходимо поместить импорт в функцию или класс, чтобы избежать проблем с циклическим импортом. Gordon McMillan советует:

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

Может оказаться необходимым переместить импорт из начала файла, если один из модулей платформно-зависимый. В этом случае импорт всех модулей в начале файла окажется невозможным. В этой ситуации хорошим решением будет импорт нужных модулей в соответствующем платформно-зависимом коде.

Переносите импорт во вложенные области видимости, такие как определения функций, только если Вы столкнулись с проблемой, например циклического импорта, или если Вы пытаетесь сократить время инициализации модуля.

Эта техника полезна, если многие из импортов не являются необходимыми, и зависят от того, как программа будет исполняться. Вы также можете поместить импорт в функцию, если конкретные модули используются только в этой функции. Обратите внимание, что загрузить модуль в первый раз может оказаться дорого из-за задержки на инициализацию модуля, однако повторные загрузки «бесплатны», они стоят только пары поисков в словарях. Даже если имя модуля исчезло из области видимости, модуль скорее всего до сих пор находится в sys.modules.

Почему значения по умолчанию разделяются между объектами?

Этот тип ошибки часто встречается среди начинающих. Предположим, функция:

В первый раз, когда вы вызываете функцию, mydict содержит одно значение. Второй раз, mydict содержит 2 элемента, поскольку, когда foo() начинает выполняться, mydict уже содержит элемент.

Часто ожидается, что вызов функции создаёт новые объекты для значений по умолчанию. Но это не так. Значения по умолчанию создаются лишь однажды, когда функция определяется. Если этот объект изменяется, как словарь в нашем примере, последующие вызовы функции будут использовать изменённый объект.

По определению, неизменяемые объекты (числа, строки, кортежи и None), безопасны при изменении. Изменение изменяемых объектов, таких как словари, списки, и экземпляры пользовательских классов может привести к неожиданным последствиям.

Поэтому, хорошей практикой является не использовать изменяемые объекты в качестве значений по умолчанию. Вместо этого, используйте None и внутри функции, проверяйте аргумент на None и создавайте новый список/словарь. Например, не пишите:

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

Как передать опциональные или именованные параметры из одной функции в другую?

Получить такие параметры можно с помощью спецификаторов * и ** в списке аргументов функции; они возвращают кортеж позиционных аргументов и словарь именованых параметров. После этого Вы можете передать их в другую функцию, используя в её вызове * и **:

Почему изменение списка ‘y’ изменяет также список ‘x’?

Если вы написали код:

вы, возможно, будете удивлены тому, что добавление в y изменяет также и x.

Два факта приводят к такому результату:

  • Переменные — это просто ссылки на объекты. y = x не создаёт копию списка — это просто создаёт переменную y, которая ссылается на тот же объект, что и x.
  • Списки изменяемы.

После вызова append, содержимое объекта было изменено с [] на [10]. Поскольку x и y ссылаются на один и тот же объект, использование любого из них даёт нам [10].

Если мы используем неизменяемые объекты:

мы можем видеть, что x и y больше не равны, поскольку числа неизменяемы, и x = x + 1 не изменяет число 5 путем увеличения. Вместо этого, создаётся новый объект 6 и присваивается переменной x (то есть, изменяется то, на какой объект ссылается x). После этого у нас 2 объекта (6 и 5) и 2 переменные, которые на них ссылаются.

Некоторые операции (например y.append(10) и y.sort()) изменяют объект, в то время, как внешне похожие операции (например y = y + [10] и sorted(y)) создают новый объект. Вообще в Python (и во всех случаях в стандартной библиотеке), метод, который изменяет объект, возвращает None, чтобы помочь избежать ошибок. Поэтому, если вы написали

думая, что это даст вам отсортированную копию y, вы вместо этого получите None, что скорее всего приведёт к легко диагностируемой ошибке.

Однако, существует один класс операций, где одна и та же операция ведёт себя по-разному с различными типами: расширенные операторы присваивания. Например, += изменяет списки, но не кортежи или числа (a_list += [1, 2, 3] эквивалентно a_list.extend([1, 2, 3])) и изменяет список, в то время, как some_tuple += (1, 2, 3) и some_int += 1 создают новый объект.

Если вы хотите знать, ссылаются ли 2 переменные на один объект или нет, вы можете использовать оператор is, или встроенную функцию id.

Как создавать функции более высокого порядка?

Есть два пути: использовать вложенные функции или вызываемые объекты. Например, с использованием вложенных функций:

Использование вызываемого объекта:

В обоих случаях,

даёт функцию, что (к примеру) taxes(10e6) == 0.3 * 10e6 + 2.

Использование вызываемого объекта — немного медленнее, и в результате получается больше кода. Однако, заметьте, что несколько функций могут разделять свою сигнатуру с помощью наследования:

Объект может сохранять свое состояние для нескольких вызовов:

Здесь inc, dec, reset выступают в роли функций, которые разделяют одну и ту же переменную.

Как скопировать объект в Python?

В общем случае, с помощью модуля copy.

Некоторые объекты можно скопировать более просто. Словари имеют метод copy:

Последовательности могут быть скопированы путём срезов:

Как узнать доступные методы и атрибуты объекта?

dir(x) возвращает список методов и атрибутов.

Как можно узнать имя объекта?

Вообще говоря, никак, поскольку объекты в действительности не имеют имён. Важно: присваивание всегда связывает имя с объектом. Это верно и для инструкций def и class.

Возможно, класс имеет имя: однако, хотя он связан с двумя именами и запрашивается через имя B, созданный экземпляр всё ещё считается экземпляром класса A. Однако, невозможно сказать, имя экземпляра a или b, поскольку оба они связаны с одним и тем же значением.

Какой приоритет у оператора «запятая»?

Запятая не является оператором в Python.

Поскольку запятая — не оператор, но разделитель между выражениями, пример выше исполняется как если бы было введено:

То же самое верно и для операторов присваивания (=, += и другие). Они не являются операторами как таковыми, а лишь синтаксическими разделителями в операциях присваивания.

Есть ли в Python эквивалент тернарного оператора «?:» в C?

Можно ли писать обфусцированные однострочники?

Не пытайтесь это делать дома!

Почему -22 // 10 равно -3?

Поскольку i % j имеет тот же знак, что j. А ещё

Как можно изменить строку?

Никак, поскольку строки неизменяемы. В большинстве ситуаций, нужно просто сделать новую строку из различных частей. Однако, если так нужно, можно использовать io.StringIO, либо модуль array:

Как использовать строки для вызова функций/методов?

Существует несколько приёмов.

  • Лучший — использование словаря, ставящего соответствие строке функцию. Его главное достоинство — строки не обязаны совпадать с названиями функций.


  • Использование встроенной функции getattr:
  • Использование locals или eval (не рекомендуется)

Как удалить все символы новой строки в конце строки?

Можно использовать S.rstrip("\r\n") для удаления символов новой строки, без удаления конечных пробелов:

Как удалить повторяющиеся элементы в списке?

Как создать многомерный список?

Возможно, вы попробуете этот неудачный вариант:

Это выглядит правильно, если напечатать:

Но если вы присвоите значение, то оно появится в нескольких местах:

Причина в том, что оператор * не создаёт копию, а только ссылку на существующий объект. *3 создаёт список из 3 ссылок на один и тот же список. Изменение в одной строке изменяют другие, что, вероятно, не то, что вы хотите.

Возможные пути решения:

Или, можно использовать специальные модули, предоставляющие матрицы. Наиболее известным является NumPy.

Почему a_tuple[i] += [‘item’] не работает, а добавление работает?

Это из-за того, что расширенный оператор присваивания — оператор присваивания, а также из-за разницы между изменяемыми и неизменяемыми объектами в Python.

Это обсуждение относится в общем, когда расширенные операторы присваивания применяются к элементам кортежа, которые указывают на изменяемые объекты, но мы будем использовать список и +=, как образец.

Если вы напишете:

Причина исключения должна быть понятна: 1 добавляется к объекту a_tuple[0], но когда мы пытаемся присвоить результат, 2, к первому элементу в кортеже, мы получаем ошибку, поскольку мы не можем изменить элемент кортежа.

То есть, это выражение делает следующее:

Когда мы пишем что-то вроде:

Исключение немного более неожиданное, но более удивителен тот факт, что, несмотря на ошибку, элемент добавился!

Чтобы понять, что случилось, нужно знать, что:

  • Если объект определяет метод __iadd__, он вызывается, когда выполняется +=, и возвращенное значение используется для присваивания
  • Для списков, __iadd__ эквивалентен вызову extend для списка

Таким образом, наш пример с кортежом эквивалентен:

__iadd__ завершился успешно, и список увеличился, но присваивание законилось ошибкой.

Переменные в Python

В данном уроке мы рассмотрим чрезвычайно важную концепцию языка Python: переменные. Они позволят нам запоминать, переиспользовать и передавать данные в программах. Поскольку переменные можно найти в любом современном языке программирования, поэтому вам уже могут быть знакомы основные концепции. Однако я настоятельно рекомендую прочитать статью даже тем, для кого Python является не первым языком, поскольку здесь будут разобраны особености, которые не имеют аналогов в других языках.

Объявление переменных

Во первых стоит отметить что Python является языком с динамической типизацией. Это означает что любая переменная может содержать любые значение. Это отличается от тех же переменных, например, в C++. Там нужно явно указывать тип, значение которого будет содержать переменная.

Теперь давайте посмотрим как мы можем создать переменную и присвоить ей значение:

В данном примере мы создаем две переменные: foo и bar . Первая переменная содержит число, а вторая строку. Подробнее о типах в Python в следующем уроке. Как видите, для того чтобы присвоить переменной значение достаточно слева от оператора = указать ее имя, а с права ее значение. Если во время присваивания такой переменной нет, то интерпретатор Python’a создаст новую переменную с указанным именем и присвоит ей указанное значение.

Переменные в Python следует именовать в нижнем регистре и слова разделять нижним подчеркиванием: _ . Например: max_age , init_state .

После объявления переменной мы можем ее использовать в любом выражении. В нашем примере, мы передали переменную bar в функцию print() .

Вот результат работы программы:

Мы также можем указать значение для нескольких переменных за одну операцию:

Как быстро конкатенировать строки в Python

Как вы, наверное, знаете один из принципов в Python: “Должен быть один и только один способ сделать что-либо”. Можете убедиться в этом, выполнив в в интерпретаторе import this (вы увидите Дзен Python). Несмотря на это, иногда вам всё равно приходится выбирать между несколькими способами сделать что-то, и не всегда очевидно, какой способ лучше. Недавно один студент спросил меня, какой способ конкатенации строк в Python самый эффективный. Я решил поделиться результатом своего маленького исследования и с вами.

Для начала вспомним, какие способы объединения строк предоставляет нам Python. Во-первых, это оператор + :

Также мы можем использовать оператор % , который, конечно, может использоваться не только для соединения строк, но и для этого тоже:

Есть и ещё более современная замена % — это str.format :

Так же, как и % , этот метод гораздо мощнее, чем обычный + , но тем не менее строки соединяют и с его помощью.

Как же мы будем замерять время? В Jupyter (так же известном, как IPython) мы можем использовать магическую команду timeit для запуска кода. Для запуска я подготовил четыре функции, каждая из которых складывает строки разным образом. Исходные строки хранятся в глобальных переменных ( x и y ), а локальная (для каждой функции) переменная z содержит результат сложения. Затем функция возвращает результат.

Конечно concat3() и concat4() фактически одинаковы, но я решил проверить и то, влияет указание порядка строк на скорость или нет. Затем я определил наши глобальные переменные:

И запустил наши функции:

Результат оказался следующим:

  • concat1: 153 наносекунды;
  • concat2: 275 наносекунд;
  • concat3: 398 наносекунд;
  • concat4: 393 наносекунды.

Здесь мы можем видеть, что concat1() , который использует оператор + , выполняется гораздо быстрее остальных. Это немного расстроило меня, потому что мне очень нравится str.format , однако теперь в задачах, которые требуют огромного количества обработки строк, от него придётся отказаться.

Возможно, такие результаты могут быть связаны с тем, что короткие строки не создаются в Python каждый раз снова, а хранятся в специальной таблице? Давайте попробуем изменить наши глобальные переменные следующим образом:

Теперь мы получим следующие результаты:

  • concat1: 2.64 микросекунды;
  • concat2: 3.09 микросекунды;
  • concat3: 3.33 микросекунды;
  • concat4: 3.48 микросекунды;

Да, каждый из методов теперь работал гораздо дольше, однако общий результат не изменился — оператор + по прежнему лидирует. Заметим так же, что разница во времени между третьим и четвёртым методом, как и ожидалось, пренебрежимо мала.

21 ноября в 19:00, Москва, беcплатно

После этого я попробовал не объявлять переменные глобальными, а задавать их в теле метода, но на результаты это всё равно не повлияло. Разумеется, можно проводить ещё много разных опытов (например, попробовать сложить больше, чем две строки), однако этого уже достаточно, чтобы иметь примерное представление о скоростях работы различных способов сложения строк в языке Python.

Django — Python. Как сложить две переменные со значением времени?

Начинаю серию переводов с Real Python.

PEP 8 (иногда PEP8 или PEP-8) — документ, который содержит набор рекомендаций и практик, про то, как писать на Python. Написан в 2001 Гуидо ван Россумом, Барри Уорсо и Ником Когхланом. Основной целью PEP 8 является улучшение читаемости и согласованности кода.

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

В этом руководстве излагаются основные рекомендации, изложенные в PEP 8. Руководство предназначено для начинающих и программистов среднего уровня, и поэтому не затронуты некоторые из наиболее сложных тем. Вы можете узнать об этих темах, прочитав полную документацию по PEP 8 (англ и рус).

К концу этой статьи, вы сможете:

* Написать код Python, соответствующий PEP 8

* Понять обоснование руководящих принципов, изложенных в PEP 8

* Настроить среду разработки так, чтобы вы могли начинать писать Python код, совместимый с PEP 8

Читаемость имеет значение. (c) Дзен Python

PEP 8 существует для улучшения читабельности кода Python. Но почему так важна читабельность? Почему написание читаемого кода является одним из главных принципов языка Python?

Как сказал Гвидо ван Россум: «Код читается гораздо чаще, чем пишется». Вы можете потратить несколько минут или целый день на написание фрагмента кода для обработки аутентификации пользователя. После того, как вы написали, вы никогда не будете писать этот код снова. Однако вам определенно придется прочитать его заново. Этот фрагмент кода может остаться частью проекта, над которым вы работаете. Каждый раз, когда вы возвращаетесь к этому файлу, вы должны помнить, что делает этот код и почему вы его написали, поэтому читаемость имеет значение.

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

Следование PEP 8 особенно важно, если вы ищете работу разработчиком. Написание четкого, читаемого кода демонстрирует профессионализм. Он скажет работодателю, что вы понимаете, как правильно структурировать свой код.

Если у вас большой опыт написания кода на Python, возможно, вам придется сотрудничать с другими разработчиками. Написание читаемого кода здесь имеет решающее значение. Другим людям, которые, возможно, никогда раньше не встречали вас и не видели ваш стиль кодирования, придется читать и понимать ваш код. Наличие руководств, которые вы соблюдаете и узнаёте, облегчит другим чтение вашего кода.

Явное лучше, чем неявное (с) Дзен Python

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

Примечание. Никогда не используйте однобуквенные имена l (прим: строчное L), O или I (прим: прописное i), поскольку их можно принять за 1 и 0, в зависимости от гарнитуры:

O = 2 # Это может выглядеть так, будто вы пытаетесь переопределить ноль, как число два

Функции — используйте строчное слово(-а). Разделяйте слова нижним подчеркиванием для улучшения читаемости. Например: function, my_function

Переменные — используйте строчную букву, слово или слова. Разделяйте слова нижним подчеркиванием, чтобы улучшить читаемость. Например: x, var, my_variable


Классы — начинайте каждое слово с заглавной буквы. Не разделяйте слова подчеркиванием. Этот стиль называется ВерблюжийРегистр (прим: чаще всего употребляется всё же английский вариант названия: кэмэл кейс). Например: Model, MyClass

Методы — используйте строчные слова или слова. Разделяйте слова нижним подчеркиванием, чтобы улучшить читаемость. Например: class_method, method

Константы — используйте заглавные буквы, слово или слова. Разделяйте слова подчеркиванием, чтобы улучшить читаемость. (прим: в Python нет отдельного типа для констант. А так как в Python существует благодаря тому, что есть много соглашений, которые должны соблюдаться разработчиками. Поэтому и используется данное обозначение для констант. ) Например: CONSTANT, MY_CONSTANT, MY_LONG_CONSTANT

Модули — используйте короткое строчное слово(-а). Разделяйте слова нижним подчеркиванием, чтобы улучшить читаемость. Например: module.py , my_ module.py

Пакеты — используйте короткое строчное слово(-а). Не разделяйте слова подчеркиванием. Например: package, mypackage

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

Как выбрать имена

Выбор имен для ваших переменных, функций, классов и т.д. может быть сложной задачей. При написании кода вы должны тщательно продумать свои варианты именования, так как это сделает ваш код более читабельным. Лучший способ назвать ваши объекты в Python — это использовать описательные имена, чтобы прояснить, что представляет собой объект.

При именовании переменных у вас может возникнуть желание выбрать простые однобуквенные строчные имена, например, x. Но, если вы не используете x в качестве аргумента математической функции, неясно, что представляет собой x. Представьте, что вы храните имя человека в виде строки и хотите использовать нарезку строк, чтобы по-разному форматировать его имя. Вы можете получить что-то вроде этого:

Это будет работать, но вы должны будете отслеживать, что представляют собой x, y и z. Это также может сбивать с толку соавторов. Более ясный выбор имен представляет из себя что-то вроде этого:

name = ‘John Smith’

first_name, last_name = name.split()

print(last_name, first_name, sep=’, ‘)

Точно так же, чтобы уменьшить количество набираемого текста, может возникнуть соблазн использовать сокращения при выборе имен. В приведенном ниже примере мы определили функцию db (), которая принимает один аргумент x и удваивает его:

На первый взгляд это может показаться разумным выбором. db () может легко быть сокращением для удвоения. Но представьте, что вы вернетесь к этому коду через несколько дней. Возможно, вы забудете, что хотели сделать с помощью этой функции, и это затруднило бы возможность понять, как вы сокращали ее.

Следующий пример понятнее. Если вы вернетесь к этому коду через пару дней после его написания, вы все равно сможете прочитать и понять назначение этой функции:

Та же философия применима ко всем другим типам данных и объектам в Python. Всегда старайтесь использовать максимально сжатые, но описательные имена.

Красиво лучше, чем некрасиво. (c) Дзен Python

То, как вы выкладываете свой код, играет огромную роль в его читабельности. В этом разделе вы узнаете, как добавить вертикальный пробел для улучшения читабельности вашего кода. Вы также узнаете, как обрабатывать ограничение в 79 символов, рекомендованное в PEP 8.

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

Окружите функции и классы верхнего уровня двумя пустыми строками. Функции и классы верхнего уровня должны быть достаточно автономными и обрабатывать отдельные функции. Имеет смысл разместить вокруг них дополнительное вертикальное пространство, чтобы было ясно, что они разделены:

Определения метода внутри классов с одной пустой строкой. Внутри класса все функции связаны друг с другом. Рекомендуется оставлять между ними только одну строчку:

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

В приведенном ниже примере есть функция для расчета дисперсии списка. Это двухэтапная проблема, поэтому я обозначил каждый шаг, оставив между ними пустую строку. Существует также пустая строка перед оператором возврата. Это помогает читателю ясно увидеть, что возвращается:

for number in number_list:

sum_list = sum_list + number

mean = sum_list / len(number_list)

for number in number_list:

sum_squares = sum_squares + number**2

mean_squares = sum_squares / len(number_list)

return mean_squares — mean**2

Максимальная длина линии и разрыв строки

PEP 8 предполагает, что строки должны быть ограничены 79 символами. Это позволяет открывать несколько файлов рядом друг с другом, а также избегать переноса строк.

Конечно, сохранение утверждений длиной до 79 символов не всегда возможно. В PEP 8 изложены способы, позволяющие операторам выполнять несколько строк.

Python примет продолжение строки, если код содержится в круглых, квадратных и фигурных скобках:

def function(arg_one, arg_two,

Если невозможно использовать подразумеваемое продолжение, то вместо него можно использовать обратную косую черту:

from mypkg import example1, \

Однако, если вы можете использовать подразумеваемое продолжение, то вам следует всё же использовать продолжение.

Если разрыв строки должен происходить вокруг бинарных операторов, таких как + и *, это должно происходить перед оператором. Это правило вытекает из математики. Математики сходятся во мнении, что разрыв перед двоичными операторами улучшает читаемость. Сравните следующие два примера.

Ниже приведен пример разрыва перед бинарным оператором:

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

Теперь давайте рассмотрим пример разрыва после бинарного оператора:

Здесь сложнее увидеть, какая переменная добавляется, а какая вычитается.

Прерывание перед бинарными операторами создает более читаемый код, поэтому PEP 8 поощряет это. Код, который постоянно ломается после бинарного оператора, по-прежнему соответствует PEP 8. Тем не менее, вам рекомендуется разрывать перед двоичным оператором.

В следующей части рассмотрим отступы и как правильно комментировать код.

Все права принадлежат авторам статьи (команде Real Python).
Мною лишь переведена и адаптирована статья.

Спасибо за внимание!

[Django] Уроки на примере реального web проекта

Всем доброго времени суток.

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

Разработка будет вестись на Django, я являюсь главным разработчиком.

Очень давно на Пикабу и всегда рад рассказать что-то новое сообществу.

Мне нужно знать интересна эта тема и стоит ли публиковать посты по этапам разработки приложения. Комментарий для минусов внутри.

Принцип 90 на 10

Вторая после Букваря

В магазине игрушек выбирали с женой книжки на НГ для детей. Это вам не Пеппу разукрашивать!

Яндекс.переводчик для Linux на Python GUI

Довольно давно возникла необходимость в мультиязычном онлайн переводчике при закрытом браузере.

Нет, так то я и словарем в «особо тяжелых» случаях пользоваться не брезгую, но иногда приходится читать немаленький текст, и не все слова я знаю, как следствие теряется контекст.

Translate-shell вещь достаточно удобная, особненно, если пишешь, допустим, в Vi/vim. Переключился в соседнюю консоль и переводи.

Ключи простейшие и запоминаются легко.

Но этого как обычно было мало. Захотелось графики.

Работа в SublimeText и Zeal несколько удобней, нежели голая консоль.

Хм… Подумал-подумал, и решил прикрутить переводчик на горячую клавишу.

Выбор пал на gxmessage. Zenity меня не устроил, уж и не помню почему.

Был написан код:

Некоторое время меня это устраивало. На «контрол+1» с английского, «контрол+2» на английский. Хорошо.

Но тут translate-shell начал давать сбои.

Не знаю, что произошло у разрабов, но меня это совсем огорчило.

Я решил, пора, давно на питоне не писал.

Недолгие поиски в гугл привели меня к Yandex.API, Python и GTK+ 3 в виде модуля gi.

Почему gi, ведь обычно писал на PyQt5? Он на моей машине работает значительно быстрее. Машина не новая, памяти тоже(по современным меркам) не ахти.

В итоге имею автопереводчик на горячей клавише.

Всем спасибо за внимание.

Видеоуроки Python

Короче, есть чувак, зовут Баки Робертс, на ютубе у него целая серия обучалок по разным языкам программирования, включая и питон, есть ли смысл мне их перевести и озвучить, а потом выложить сюда? Объясняет он очень круто и постепенно, я с нуля начинал и мне довольно легко давались его обучалки. Вот ссылка на плейлист по питону:

[Основы] Часть 1. Для грудничков.

Предполагается, что пост http://pikabu.ru/story/hello_world_4265035 уже прочитан или у вас любой дистрибутив linux.

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

Предполагается, что аудитория состоит не из овощеподобных амёб, а развитых людей, готовых применять свою черепную коробку не только для того, чтобы есть.


Для начала замануха. Можно много писать о том, какой питон крутой, что его используют для бигдаты, датасаенса, веб-разработки и всего остального. Но это всё сухие слова. Поэтому приведу пару примеров того, где питон используется в качестве основного языка.

Instagram — всеми любимый хостинг фотографий еды и ёбл тупых пёзд. Да, он написан на питоне. Мало того, за фреймворк взят Django, до которого мы доползём, если кроме меня будут желающие ползти. Да ещё и HTTP-сервер они взяли Gunicorn, до которого мы так же доползём. В качестве БД они используют PostgreSQL — мою любимую РСУБД и именно поэтому до неё мы тоже, возможно, доползём.

Reddit — сервис смехуёчков, думаю, все о нём так или иначе слышали. Он написан также на питоне, но на Pyramid фреймворке, а не Django. В качестве БД используются две базы: Cassandra и PostgreSQL. В качестве кэша используется memcached и фейсбуковский mcrouter. В качестве брокера сообщений используется RabbitMQ. Исходный код находится в общем доступе здесь https://github.com/reddit/reddit

exchange.livejournal.com — биржа блогеров ЖЖ, которая недавно открылась. Почему она здесь? Потому что я участвовал в её разработке. Она также написана на Django с базой PostgreSQL.

На этом замануха кончается и начинается моя нелюбимая часть — циклы, ветвления и переменные.

Все куски кода будут являть собой скриншоты Jupyter Notebook, во-первых, потому что мне в нём удобно писать, во-вторых, потому что нечего копировать чужой код.

Питон — язык со строгой динамической типизацией. Что это значит?

— Если захочешь сложить число 5 со строкой ‘7’ — тебя наругают. Это называется строгой типизацией. Никаких преведений к «более общему» типу.

— Если в переменной x хранилось число, это не значит, что ей нельзя присвоить строку. Это динамическая типизация. Тип переменной, разумеется, нигде указывать не нужно.

Приятной возможностью является параллельное присваивание. Обмен значениями также поддерживается.

Есть также множественное присваивание, которое я настоятельно не рекомендую использовать бездумно (это касается неплоских типов данных, о которых поговорим как-нибудь позже):

С переменными, вроде, пока всё.

В отличии от Си-подобного синтаксиса, у нас нет ни фигурных скобок для выделения блоков, ни скобок для выделения условного выражения (на самом деле, ничего не мешает обернуть условие в скобки). Блоки выделяются ТОЛЬКО отступами. Здесь нет никаких switch, есть только if, elif и else. Следующий пример, думаю, объяснит всё за меня:

А теперь небольшой сюрприз. Несмотря на то, что язык имеет строгую типизацию, сравнения между некоторыми неодинаковыми типами данных (int, float, Decimal) поддерживаются. Например 5 == 5.0 вернёт True, несмотря на то, что 5 — это целое число, а 5.0 — с запятой. Но использование этого считается дурным тоном.

Если вы до этого дня не знали слово «итератор» и писали только циклы по индексам, вроде такого for(int i=0; i

Для обычных циклов по индексам существует генератор range. О генераторах тоже позже.

Функции в питоне объявляются двумя способами:

Однако, второй способ СТРОГО НАСТРОГО рекомендую использовать для определения обычных функций. Лямбда-функции (или безымянные функции) нужны только для того, чтобы передавать их аргументом в функции высшего порядка.

Тут, наверное, возникло сразу два вопроса:

Как можно передать функцию аргументом в другую функцию?

Что такое функция высшего порядка?

Т.к. питон — объектно-ориентированный, следовательно, всё в нём является объектом. И функция тоже. Аргументом в функцию может прийти любой объект, в т.ч. и функция:

В данном примере много чего интересного:

1) После определения функции (def) можно ввести так называемый docstring, который описывает то, что делает функция. При этом, этот докстринг сохраняется в атрибут __doc__ объекта функции (что только лишний раз говорит о том, что функция — объект)

2) __name__ атрибут содержит имя объекта (функции или класса)

3) h в этом случае — функция высшего порядка. Функция высшего порядка — это функция, которая принимает или возвращает другую функцию. Это пригодится для декораторов, о которых также позже.

Функции можно присваивать другим переменным:

Но имя (__name__) останется прежним, т.к. фактически, f и same_func только лишь ссылаются на функцию.

Чёт, кажется, я уже далеко забрёл. В следующей части, если увижу интерес у аудитории, я расскажу о стандартных структурах данных (списки, кортежи, словари, множества) и о том, какие они охуенные и для чего используются.

P.S. Пост писался без подготовки, прямо в редактор постов на пикабу, обо всех недочётах пишите в комментах, закидывайте тапками и помидорами.

Как я изучал(изучаю фреймворк Django). Личный опыт.

Все что далее, — мой личный опыт изучения фреймворка Django. Может быть пригодится таким же новичкам в программировании как и я.

Что нужно знать (необходимый МИНИМУМ) относительно Python:

-Ввод и вывод данных

-Функции и рекурсия

-Работа с модулями и функциями (создание, импортирование, вызов. )

-Основы регулярных выражений

В настоящее время, актуальной версией является Django 2.0. Но я советую начать изучение с версии 1.11. Почему именно так:

1. По Django 2.0 мало различных материалов на русском языке. Для 1.11 материалов достаточно.

2. Django 2.0 и 1.11 очень похожи, но в 2.0 сделали упрощённый синтаксис маршрутизации URL. Из-за этого могут возникнуть сложности на начальном этапе, если пытаться обучаться по материалам основанным на 1.11 версии.

3. Большинство готовых приложений и расширений до сих пор поддерживают только 1.11 версию и не поддерживают 2.

4. Расширенная поддержка версии 1.11LTS заканчивается в 2020 году, а 2.2LTS пока не видно.

Итак, расскажу как изучал я. Может быть кому-нибудь покажется полезной данная информация.

I. -НАЧАЛО («копипастим» свой первый проект):

-понять как работает фреймворк(установка, как создается проект, архитектура, как взаимодействуют его основные компоненты — urls, модели, шаблоны, views)

1. Проходим туториал на Django-girls.

Шаг за шагом копипастим и пытаемся понять что вообще происходит.

-Основы работы в консоли Linux

-Создание и работа в виртуальном окружении Python.

-Основы основ Django (urls, модели, шаблоны, views)

Альтернативный вариант (более короткий):

Учебник официальная документация (docs.djangoproject.com/en/1.11 — раздел FirstSteps). Или перевод документации с портала djbook.ru

Версия 1.9 а не 1.11, но в этом нет ничего страшного.

2. Цикл лекций «Web-технологии. Разработка на DJANGO» от Mail.ru

Если не интересны основы-основ про web-разработку (уже знаете или задача быстро освоить Django), тогда начинаем смотреть с «9. Web-технологии. MVC фреймворки | Технострим» и дальше.

-Архитектуре и принципам взаимодействия компонентов, основам Django

3. Книга «Django: практика создания Web-сайтов на Python» Владимир Александрович Дронов:

ссылка: сами кУпите или найдёте.

Читаем главы с 1 по 7. Главу 2 опционально можете пропустить, если знакомы с основами Python.

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

-Пониманию основ MVC

-Через примеры кода начнет приходить понимание, как все работает.

-Через копипасту проекта в общем виде начали понимать как все устроено и работает

-Через лекции MAIL.ru узнали как работают web-приложения, как выглядит архитектура типичного web-приложения(взаимодействие бекенда-фронтэнда, работа протоколов, общая архитектура), узнали место Django в этой архитектуре

-Через книгу более детально познакомились с паттерном проектирования MVC (что такое модель, контроллер, представление), через примеры кода начали понимать как это может работать.

II. ПРОДОЛЖЕНИЕ НАЧАЛА(продолжаем «копипастить»):

1. Ищем курс «iTBursa Python&Django». Продажу курса уже закрыли (скорее всего видимо потому, что курс попал в открытый доступ). В курсе есть основы Python и Django. Плюсом идут основы: html/css, bootstrap web, http, databases, linux, shell, git/github, nginx, deployment.

Продолжаем копипастить уже по этому курсу, но теперь самостоятельно выполняем «Контрольные задания»(или не выполняем). В принципе этот курс мог бы заменить все вышеперечисленное. Но так как каждый человек воспринимает информацию по разному, ИМХО лучше усвоится информация, полученная из разных (по типу и виду подачи информации) источников.

Дополнительно: курс itvdn-Django от Антона Мазуна

2. Продолжаем читать и перечитывать Дронова

3. Изучаем официальную документацию или перевод документации 1.9(djbook.ru)

-На этом этапе уже должно быть освоено достаточное количество материалов для написания своего собственного приложения.

II. КОНЦА НЕ ВИДНО(создаём свой собственный проект):

Собственно если все делали правильно, на этом этапе должны быть все необходимые знания для реализации собственного проекта. По сути, можно сосредоточиться только на Джанго, а фронтэнд слепить из кусков Bootstrap.

Теперь отправляемся в свободное плавание на просторы интернета. Теперь уже сами ищем статьи, видео, гайды, бестпрактис. Продолжаем читать Дронова и переходим на актуальную версию Django 2.x

Дополнительно можно начать читать:

-Django подробное руководство. Адриан Головатый. Джейкоб Каплан-Мосс. Книга очень старая (2010), многое изменилось, но общие принципы остались те же.

-Tango with Django. Многие советуют эту книгу.

Вот ещё парочка:

-Web Development with Django cookbook

Извиняюсь за возможные орфографические, и в особенности, за пунктуационные ошибки.


ЗЫ. Кстати, в комментах к моему предыдущему посту (Моя история: опыт изучения программирования) и по почте многие высказывали мысль о создании канала в Телеграмм по данной тематике. Такой канал я создал. Не знаю можно ли ссылку(или нет). Называется python_noobs(PythonNoobs). Сейчас там 12 человек(в основном пикабушники с предыдущего поста — всем кому рассылал свою подборку материалов). Создан чисто для новичков. На канале обмениваемся опытом изучение Python и смежных технологий, делимся ссылками на полезные материалы(статьи, видео, гайды, курсы. ), собираем команду для совместных проектов и просто общаемся, чтобы не прокрастинировать :)

Для начинающих изучать программирование(Python)

Следует отметить, что python-лучший выбор для новичка, желающего приступить к изучению программирования. Однако это тема не для одного поста. Да и изучение программирования должно быть построено не на одном лишь языке, а включать себя несколько составляющих предметов, но этот пост именно для тех, кто знает что хочет учить питон, но не знает какую именно литературу ему выбрать.

1.Майкл Доусон — Программируем на python

Начать стоит именно с этой книги. Без излишнего углубления в язык рассматриваются его основы. Весь материал подкреплен множеством примеров, в основном связанных с игровой тематикой. Глава строится так: в самом начале дается программа, подобную которой вы сможете написать по прочтении главы, ну а по ходу изучения сталкиваешься с рядом более простых программ, приводящих к пониманию основной. Это буквально наводняет книгу примерами, и дает необходимую практику новичкам. Ну и разумеется подталкивает к созданию своих собственных программ.

Отличная книга, но слишком подробная для новичка, читать ее стоит в связке с практикой. Нечто вроде: вы захотели написать программу, но вам не хватает более глубоких знаний что бы сделать ее удобней/короче/красивей и т.д.

3.Марк Саммерфилд — Программирование на Python 3

Присутствует та же динамика что и в первой книге, нет лишней информации, однако она сложнее, все не так разжевано как у Доусона. Стоит отметить что после прочтения Доусона, освоение данной книги особо труда не составит.

4.Марк Лутц — Программирование на Python

Книга учит применять знания полученный в «Изучаем Python 4-е издание», однако так же перегружена лишней для новичков информацией, воспринять которую будет куда проще после Доусона и Саммерфилда. Эта книга-некий финиш в начальном изучении языка. Освоив ее вы сможете перейти куда к более углубленным работам.

Надеюсь кому то поможет эта подборка. Приятного чтения и удачи в обучении.

Hello world!

Я писал тут об одной мощной, простой, интересной библиотеке, которой пользуюсь чуть ли не каждый день, но вдруг осознал, что первый пост лучше сделать просто ознакомительным, для тех, кто совсем-совсем новичок. :)

Поэтому сегодня мы немного поговорим о том, что такое вообще python и попробуем завести его на своём компьютере.

Если ты уже программируешь на python, то этот пост ну прям явно не для тебя. :) Ты можешь просто не читать его вовсе, а лучше написать сюда свой, про что-нибудь интересное из твоего опыта! С преферансом и поэтессами, как полагается. ;)

Итак, как сообщает нам достоверный источник (википедия), python (я произношу «пайтон», некоторые русскоязычные люди говорят «питон») — язык программирования общего назначения, ориентированный на повышение производительности разработчика и читаемости кода. Иными словами, на нём можно быстро и писать код, и разбираться в том, что написал сосед.

Несмотря на кажущуюся из определения простоту, он имеет колоссальные возможности благодаря поддержке сразу нескольких парадигм программирования, большому числу функций из коробки (в стандартной библиотеке), и, конечно, расширяемости, благодаря огромному количеству легко устанавливающихся библиотек нестандартных.

Применяют ли его на практике?

Безусловно! Python — очень распространённый язык! С его помощью можно делать сайты, обрабатывать данные, работать с машинным обучением и много-много ещё всего интересного. Он используется многими крупными компаниями (например, в Google, чего далеко ходить). С его помощью можно делать как простенькие скрипты для повседневной жизни, так и всерьёз заниматься научной и коммерческой разработкой.

Заинтересовало? Тогда давай попробуем написать и запустить что-нибудь на Python! :)

Важно понимать, что способов для этого — тьма! Ты можешь писать свою программу хоть в мощной среде разработки с подсветкой синтаксиса и прочими плюшками, хоть в обычном блокноте, хоть вообще в интернете (да и запускать там же). Думается, об этом будет отдельный пост. Сейчас же я просто покажу как можно исполнять команды в интерпретаторе python.

И сразу пара слов о последнем, потому что если ты это читаешь, то, быть может, и не знаешь что это такое.

Python — язык интерпретируемый. Говоря вкратце, это означает, что его инструкции выполняются (интерпретируются) одна за другой последовательно, без компилирования всего и сразу, как, например, в языке Си. Интерпретатор — это как раз-таки специальная программа, которая и занимается интерпретацией.

Чтобы пользоваться языком python, нужно скачать и установить его реализацию с официального сайта https://www.python.org/downloads/.

Я приведу пример на 3-ей серии языка python (3.5.1), поэтому рекомендую скачивать именно её. Для Windows это можно сделать напрямую по этой ссылке. При установке, не забудь поставить галочку на пункте Добавить в PATH, это упростит тебе жизнь в дальнейшем.

Скачал и установил? Отлично! Давай запустим интерпретатор. Открой командную строку (вбей в Пуск cmd) и введи туда:

Интерпретатор запущен! Да, всё так просто! Если всё сделано правильно, то будет что-то вроде:

Теперь исполним первую команду! Введи:

Да, она просто распечатала, то что в скобках, в кавычках на экран! Это выполнилась стандартная функция языка python — print(). Как видишь, здесь, в отличие от Си, например, для неё не нужно ничего присоединять, не нужно никак её обособлять (в этом конкретном случае), не нужно ничего ставить после неё.

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

Кстати, насчет арифметических операций. Ты можешь без зазрения совести совершать их прямо в функции print(). Попробуй, например, по порядку:

print(100 + 1)
print(42 / 7)
print(111111111 * 111111111)

На этом пока всё! Спасибо за внимание! Очень сложно писать первый пост в целом сообществе — не совсем понятен уровень читающих. Поэтому я решил посвятить его абсолютным новичкам. Надеюсь, не прогадал. :)

Спасибо за внимание!

Моя история: опыт изучения программирования

Привет дорогое сообщество pikabu!

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

В настоящий момент я проживаю свой 33 год в этом мире. И половину из этих лет меня восхищали художники в компьютером мире — программисты. Всегда хотелось самому научиться «писать код». И не важно что это будет: сайт, программа или небольшой скрипт. Но так уж получилось, в силу тех или иных причин, мечта всегда откладывалась в дальний ящик. В институте нам преподавали программирование на Паскаль и Делфи. Но то ли не было понимания на тот момент, или желания и большой тяги к изучению, — обучение не задалось! С трудом сдавались лабораторные работы, эта куча открывающихся и закрывающихся фигурных скобок, непонятные конструкции, компиляция кода, исправление ошибок, снова компиляция. Все это отталкивало, подрывало веру в себя, в свои силы. В голове всегда крутилась мысль «программирование наверное не мое. ». Тогда ещё не было многочисленных интернет-ресурсов, онлайн-курсов, интернет у большинства был «по карточкам» и войти в программирование была та ещё задача, если ты особо то и не понимаешь для чего тебе это нужно и в каком направлении двигаться. И вот, спустя может быть пару лет, у меня вновь появилось желание попробовать. Я пошёл в книжный магазин и накупил различных самоучителей по языку Basic. Сейчас уже и не вспомню почему тогда мой выбор остановился именно на этом языке программирования. Открыв любую книгу все начиналось как всегда «за здравие»: ну это вроде бы мне понятно, ну это ясно, ну это я знаю. Я пытался начать писать свой первый условный «калькулятор», радовался своим первым успехам, радовался тому, как достаточно легко и просто все у меня вроде бы получается. Но неизменно наступал момент, когда я переходил к новой главе книги, которую можно описать примерно так: «Итак, вы написали своё первое приложение(калькулятор), а теперь мы создадим свою первую нейтронную сеть!». То есть, каждый раз появлялась огромная пропасть, которую я не мог преодолеть. Желание освоить все и сразу играло со мной злую шутку. Мне казалось, что я знаю материал, но в реальности мои знания были поверхностными. И в определённый момент пробелов в знаниях языка становилось так много, что преодолеть пропасть непонимания следующей главы не представлялось возможным. Сложно было преодолевать первые неудачи-препятствия. В дополнение к этому наверное лень, отсутствие должной мотивации, непонимание того где и как я смогу применить полученные знания в очередной раз поставили крест на моих попытках научиться программировать. И вот, полтора года тому назад я сделал третью попытку. К этому меня подтолкнул пример коллеги по работе, который самостоятельно освоил связку php+MySQL и автоматизировал несколько бизнес-процессов на нашей и своей прошлой работе. Его код был не то чтобы ужасен, но он работал и приносил пользу людям. И я задал себе вопрос: «если он смог, чем я хуже?». В этот раз к выбору языка программирования я подошёл более ответственно. Мне не очень понравился вариант с web-ориентированным PHP. Хотелось чего-то простого, понятного, красивого, развивающегося, достаточно современного, с максимальной широтой направлений для последующего применения. Так мы с другим моим коллегой остановили свой выбор на Python и начали вместе его изучать! Python мне сразу понравился своей понятностью, лаконичностью и чистотой кода, кучей готовых библиотек и «батареек» на все случаи жизни. Python не ограничивает написание когда на основе только лишь классов(к примеру) — можешь писать как тебе нравится, и это тоже подкупало. Я прочитал кучу статей об изучении Python, где все сводилось к изучению книг Луца и Саммерфилда. Но слава богу я пошёл другим путём. Дело в том, что труды этих авторов сродни библии. В этих книгах все слишком серьезно и основательно для изучения, — они больше похожи на справочники, чем на учебные пособия. Путём «проб и ошибок» я подобрал себе другие книги и учебные материалы по Python, которые мне больше подошли. Но самое главное нашёл бесплатный онлайн-ресурс, где по каждой теме даются лишь необходимые для изучения основы и по 10-15 задач для закрепления материала раздела. Данный ресурс не позволял мне убежать вперёд, пока я не изучу материалы предыдущего раздела. Задачи этого курса относятся к так называемому «спортивному(олимпиадному) программированию». Да, они не решают каких либо реальных задач, с которыми в реальности приходится сталкиваться программистам. Но они позволяют освоить синтаксис и основные конструкции языка. То, что мне было нужно! В общем, спустя год моей борьбы с языком и с собой(лень, прокрастинация итд итп), с перерывами и остановками, но я наконец то закончил этот курс! Несколько раз сталкиваясь со сложными(для меня на тот момент) задачами я даже бросал изучение, но мысль о незаконченном деле не давала мне покоя и я вновь возвращался к прохождению курса. Хотя, наверное, хватило бы и 2-3х месяцев усиленной и целенаправленной работы, а то и того меньше при наличии свободного времени. Это где-то 130 задач на работу с основными типами данных(строки, числа, множества, списки, словари). Параллельно читал книги и другие материалы, установил приложение с Python на iPad и программировал по дороге в метро. Это наверно даже не треть того, что необходимо знать полноценному программисту на Python. Но это позволило мне начать делать свои первые реальные проекты: например спарсить данные с веб-страницы, открыть pdf документ-найти все используемые слова и перевести их через api яндекс-переводчика и так далее.

Сейчас я пытаюсь изучать фреймворк Django. Даётся с трудом. Пока что освоил базовые вещи для работы с моделями, формами и шаблонами. Но это позволило мне сделать свой первый web-проект на Django+bootstrap, который позволяет вести реестр адресатов(отправителей), создавать шаблоны конвертов на основе документов word и собственно печатать эти самые конверты.

Сейчас моя цель(если хотите мечта) к которой я хочу прийти — это создание небольшого портала(социальная сеть) для одного (скажем так) оффлайнового сообщества.

По прошествии лет, глядя сверху вниз на упущенные годы, я сделал следующие для себя выводы, которые можно описать следующими высказываниями(не моими конечно же):

1. Дорогу осилит идущий.

2. Не так страшен черт как его малюют.

3. Курочка по зернышку клюет.

4. Не боги горшки обжигают.

Главное поставить себе цель, целенаправленно идти к ней маленькими шагами и все обязательно получится и приложится!

Вот собственно и вся моя история. Надеюсь она кого-нибудь сподвигнет начать программировать: автоматизировать рутинные задачи, создать свой первый web-сайт, игру и в последствии, возможно стать полноценным разработчиком и получить свою первую работу! Для меня это уже скорее хобби и приложение к основной работе. хотя может ещё не все потеряно в мои 33 года? :)

Что хотелось бы ещё добавить: найдите себе компаньона, с которым вы могли бы вместе изучать язык программирования. Лично мне это очень помогало: всегда можно обсудить какие-то непонятные моменты, на определенных этапах присутствует «дух соперничества» и вообще вместе веселее. Будет совсем идеально если вы найдете ментора — того человека, который уже прошёл этот путь и как учитель может подсказать вам непонятные моменты.

От себя хочу добавить, что готов оказать помощь всем желающим, кто хотел бы изучить Python или Django. С радостью поделюсь хорошими электронными материалами по изучению Python(книги, видеокурсы), подскажу толковые веб-ресурсы и расскажу как изучал я, а также помогу на уровне своей компетенции в этих вопросах :) Быть может тут найдутся те, кто знает html+css+jscript и хотел бы освоить бэкэнд на Python — я думаю мы могли бы найти общий язык :)

Буду безумно признателен, если найдётся такой человек(ментор), который уже прошёл свой путь и поможет мне постичь азы web-разработки на фреймворке Django!

Сумбурные заметки про python и django

Накопилось несколько маленьких заметок/советов про python и django, которые на отдельные топики не тянут, поэтому публикую все сразу.

Под катом:

  • как упростить код вьюх ровно в 2 раза
  • легкий способ рисования графиков
  • почему Ian Bicking воскликнул «Cool!»
  • приложения для ВКонтакте на django за 5 минут
  • хорош ли pymorphy?
  • пара фишек насчет выкладки пакетов на pypi
  • что общего между декораторами и with-контекст-менеджерами
  • принимаем оплату на django-сайтах
  • показываем Яндекс.Карту для заданного адреса

Django: упрощаем код вьюх

В документации и обучающих примерах по django обычно пишут вьюхи вот так:

Наверное, это правильно — так объяснять, чтобы человек лучше понимал, что происходит. Но в реальной жизни этот код пишется ровно в 2 раза короче:

Фишки:

  • Для unbound-форм is_valid всегда возвращает False. Если после этого сразу непонятно, как работает код ContactForm(request.POST or None) , то разберитесь в качестве упражнения, расписывать не буду. Это простая и полезная идиома.
  • Всегда используйте django.shortcuts.redirect для редиректов. Он умеет реверсить названия url’ов, вызывать get_absolute_url или просто перенаправлять по url’у
  • Используйте django.views.generic.simple.direct_to_template вместо render_to_response . Они делают почти одно и то же, но direct_to_template использует RequestContext вместо Context, который и так нужен в большинстве случаев. Вместо direct_to_template можно использовать декоратор render_to из django-annoying, но это уже дело вкуса, кому как нравится.

Django: рисуем графики

В статье про админку обещал рассказать про графики, но все никак руки не доходили, нехорошо получилось. Да и рассказывать-то там особо нечего, все слишком просто и «тупо» — графики рисуются через google charts. При этом можно обойтись без всяких библиотек: конструируем себе график по вкусу тут (это полуофициальный инструмент от гугла, на него есть ссылка со справки по api google charts), а потом вставляем полученную строку в шаблон и подставляем переменные вместо тестовых значений.

Есть очень тонкая обертка над google charts: django-chart-tools. Суть — та же: собрать график визуально и заменить переменные, просто с django-chart-tools такие графики удобнее поддерживать.

Выборку данных можно делать просто через django ORM, или, для удобства/скорости, через django-qsstats-magic, в зависимости от задачи.

В итоге (с использованием django-chart-tools и django-qsstats-magic) график пользователей по дням можно вывести примерно так:

потом переменные values и captions передаем в шаблон, а там выводим график таким образом:

Ограничений по количеству обращений у google charts image api нет, там просят только связаться с ними, если > 200тыс обращений в день будет, чтобы они нагрузку распределили. Так что такие графики можно не только в админке использовать.

Django: тесты

Используйте для написания тестов django-webtest. Я уже писал про это приложение, но с того времени произошло одно очень важное изменение: django-webtest теперь предоставляет доступ к контексту шаблонов (точно так же, как и стандартный джанговский тест-клиент). Спасибо Gregor Müllegger. Теперь можно писать в таком стиле:

работает также стандартный assertTemplateUsed.

django-webtest лучше любой интеграции с twill, т.к. в них нет доступа к контексту шаблонов и полной поддержки юникода, да и twill не развивается.

django-webtest лучше стандартного тест-клиента, т.к. предоставляет простой API (попробуйте-ка засабмитить форму со значениями по умолчанию через стандартный тест-клиент). Со стандартным тест-клиентом также нельзя протестировать отсутствие csrf-токена (или очень чер окольными пуями), а с django-webtest это делается тривиально (и даже автоматически). Используйте django-webtest)

Тут бы составить попсовую табличку с фичами: у django-webtest будут везде зеленые галочки, а у twill и стандартного тест-клиента — красные то тут, то там. Даже Ian Bicking считает, что django-webtest — это «Cool!».

Django: пишем приложение для Вконтакте

Это не просто просто, а очень просто. Отличие от обычных сайтов — только в способе регистрации и входа пользователей. Вместо django-registration ставим и настраиваем django-vkontakte-iframe. Все, теперь все посетители — это зарегистрированные и авторизованные django-пользователи, в остальном можно разрабатывать обычный сайт. Разве что еще позаботиться об js, чтобы подгонять размер iframe под размер страницы.

Python/Django: работа с русским языком

Кто не знает, pymorphy — это питонья библиотека для работы с русским языком. Умеет морфологический анализ и стрелять из пушки по воробьям: например, склонять слова из базы (или простые словосочетания) прямо в шаблоне django или ставить их в нужную форму в зависимости от числа — без явного перечисления всех вариантов склонения.

pymorphy вырос из статьи на хабре. Признаюсь, код сначала не был хорош, т.к. это был мой первый опыт общения как с python, так и с nlp (обработкой естественных языков). Но морфологический анализатор был-таки написан — и заброшен на год.

В начале этого года возобновил работу над pymorphy и переписал там кучу всего. А весной прошло «соревнование» морфологических анализаторов в рамках конференции Диалог-2010. Там участвовали очень серьезные ребята, результаты проверяли профессиональные лингвисты. pymorphy по дорожке «Морфология» справился лучше всех (скорее всего из-за того, что я как раз тогда выкатил работу с составными словами, записанными через дефис). Также pymorphy был единственным участником, приславшим разбор дорожки с «гразными текстами». Это все особо ни о чем не говорит, но приятно)

Python: пара трюков для выкладки пакетов на pypi

1. В setup.py в long_description можно использовать разметку ReST. Удобно положить рядом с setup.py файлик README.rst и потом просто указать После этого на странице проекта на pypi сразу будет справка по нему — это просто, удобно, и в 90% устраняет необходимость в мороке с отдельной документацией (тут еще такое замечание — если все же кажется, что пакету нужна документация с навигацией и тд, то стоит задуматься — возможно, пакет делает слишком много?).

2. Есть сравнительно малоизвестный хак с setup.py. Если разметка выглядит не так, как хотелось, или исправили опечатку, или classifier, то делать новый релиз для исправления этих ошибок нет никакой необходимости: можно просто запустить ./setup.py register и данные обновятся.


Python: декораторы и with

Декораторы и оператор with в питоне часто применяются для одного и того же: выполнить какие-то дополнительные действия до или после определенного куска кода. А это означает, что можно написать такую штуку, которую можно использовать одновременно и как декоратор, и как контекст-менеджер для with (например, так: gist.github.com/573536).

Django: принимаем платежи на сайте

Если что, через django-robokassa и django-assist-ru сделаны в продакшне тысячи покупок, > млн рублей.

  • ROBOKASSA
  • Assist

Пишите еще, кто чем пользуется, добавлю в список.

Python/Django: показываем Яндекс.карту на сайте

Чтобы не возиться с геокодированием и кешированием, можно воспользоваться приложением yandex-maps.

Ух, будем считать, что все.

Читают сейчас

Похожие публикации

  • 13 июня 2011 в 21:33

Tips and Tricks 1: отложенные вызовы функций (Functor Manager)

PyCharm 1.5: свежий апдейт > +36 4,8k 5 48

iOS tips and tricks: Динамический Default.png

Вакансии

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Комментарии 37

Спасибо тебе добрый человек. Низкий поклон от изучающего Джанго! :)

PS: Если есть еще чем полезным поделиться для новичков — будем только рады (думаю начинающие джангисты меня поддержат)

Я обычно ещё вот так делаю:

long_description = open(‘README.rst’).read() + open(‘CHANGES.rst’).read()

«request.POST or None» — отличная идея.

Конечно, никуда без django-annoying. А еще полезны:
https://bitbucket.org/jespern/django-piston/overview
https://bitbucket.org/offline/django-publicauth/overview
https://bitbucket.org/jezdez/django-robots/overview
https://bitbucket.org/david/django-storages/overview
https://bitbucket.org/zuber/django-newtagging/overview
https://bitbucket.org/Kizlum/django-lightsearch/overview
https://bitbucket.org/slav0nic/django-flickrstorage/overview

@render_to, @ajax_request
Redirect exception
AutoOneToOneField, JSONField
HttpResponseReload

вроде мелочи, а без них потом сложно, если привыкнуть

относительно request.POST or None — если вы захотите делать вручную редактирование модели (то есть автозаполнять форму, основываясь на данных модели) — то в вашем варианте придется переписывать всю логику (в противном случае форма берет все данные из модели и сразу считает себя валидной, до POST-запроса дело не доходит). а в первом варианте будет достаточно заменить ContactForm на ContactForm(model). думаю, здесь именно такая логика, почему джанго в доках дает именно первый, развернутый вариант.

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

Какие есть параметры конструктора у формы, такие и можно данные передать) Я тут пример привел для стандартной джанговской ModelForm:

параметр конструктора instance для формы все равно ведь нужно дублировать при стандартном подходе в обеих ветках условия: unbound-форма берет из instance начальные значения, bound-форма узнает, куда все сохранять.

В случае с обычной формой (forms.Form) начальные значения (initial) ни на что не влияют, когда форма — bound, поэтому их точно так же можно передавать. Да и вообще, в большинстве случаев по логике требуются одинаковые параметры в конструкторе и там, и там.

Насчет ограничений — про «никаких ограничений» я погорячился) Правильней будет сказать, «можно почти всегда использовать» или «в большинстве случаев упрощает код».

Фишку с request.POST or None не выйдет использовать, если почему-то нужно 2 совсем разные формы в bound и unbound варианте (не знаю, зачем и когда это может понадобиться).

Еще 1 вариант есть, когда она не будет работать — если по совсем пустому POST-запросу нужно что-то делать (именно из-за этого случая проверяют request.method == ‘POST’, а не просто if request.POST).

Две разные формы могут понадобиться, если в них есть цепь последовательных , а объектов в базе слишком много, чтобы их грузить все сразу. вот и получается, что в unbound . field.queryset=SomeModel.objects.none()
а в bound
. field.queryset=SomeModel.objects.all()

Может, подскажете какой-нибудь другой подход? Этот не нравится, но ничего другого не придумалось

форма берет все данные из модели и сразу считает себя валидной

Данные для предварительного заполнения скармливаются форме через параметр initial — тогда она не будет bound, и ещё не будет почём зря выполняться процедура валидации.

Если после этого сразу непонятно, как работает код ContactForm(request.POST or None), то разберитесь в качестве упражнения, расписывать не буду. Это простая и полезная идиома.

я с вами согласен в том плане, что описание контроллеров для форм, своей однотипностью и многословностью вызывает уныние. но делать так, как вы предлагаете, тоже нельзя. :)

если контоллерная логика такая же простая как в примере — используйте create-update-delete-generic-views — будет еще короче. :)

ваш же код это грязный хак, а не «полезная идеома», т.к. в корне меняет семантику проверки. проверяя request.POST, вы делаете допущение, что при POST запросе (request.method == ‘POST’), тело HTTP сообщения (request.POST) не может быть пустым. это так:

допустим, форма предлагает выбрать один из вариантов контактов (список полей type=«radio»). если не выбрать ни одного и сделать POST, то тело POST запроса будет пустым и после перезагрузки страницы посетитель увидит снова оригинальную форму, вместо формы с сообщением об ошибке.

т.е. для какой-то конкретной формы, при данных условиях это может работать. но в общем случае — нет. вот поэтому

В документации и обучающих примерах по django обычно пишут вьюхи вот так

Если Вы все делаете «по науке» и используете защиту от CSRF, то в каждой форме есть еще CSRF-токен, и запрос POST не будет пустым никогда. Так что это не грязный хак и это будет работать в общем случае.

Если же защита от CSRF не используется, то у сайта есть проблемы посерьезные, чем отсутствие ошибок валидации в тех (редких?) случаях, когда у кнопки submit не прописан name.

какие именно проблемы? я пока вижу только одну проблему — в пресловутом сниппете нужно учитывать массу плохо контролируемых нюансов внешней среды (csrf, содержание html-формы, ajax, возможности http-клиента). а это чревато появлением ошибок на этапе развития проекта (отключив csrf вы рискуете уронить бизнес-логику).

учите писать правильно, а не экономить строчки кода. даже если «все под контролем». :)

csrf же это не «наука», а инженерное решение, которое имеет вполне конкретную область применимости: работает только для html-форм, требует поддержку кук от браузера. (кстати, именно из-за привязанности к кукам, csrf не обеспечивает защиту на под-доменах). полезная штука, в своей нише, и не нужная во всех остальных случаях. не понимаю, ради чего его вытащили из contrib в core и переворотили четверть джанги. )

«общий случай», где используются Forms (кстати, намеренно абстрагированные от request) — гораздо шире. forms часто используются для обработки данных, полученных через ajax — здесь csrf бесполезен, в принципе (кстати, и не обрабатывается django); с помощью forms удобно делать валидацию при создании api сайта. здесь csrf так же не нужен…

CSRF-защиту включили по умолчанию, чтобы не было ситуаций, как в mail.ru) Если защита от чего-то отключена по умолчанию, то это не защита — ей никто не будет пользоваться, а если и будет, то нет никаких гарантий, что пользоваться будут последовательно. Поэтому imho это правильное решение, так же, как и автоэкранирование в шаблонах, например. Автоэкранирование — это точно такое же инженерное решение, которое полезно в своей нише и не нужно в остальных случаях, но это большой плюс, что оно включено по умолчанию. Это снижает ментальную нагрузку с программиста — ему не нужно думать, как сделать приложение защищенным, ему нужно думать в тех случаях, когда защиту нужно по каким-то причинам отключать.

Вы назвали csrf, ajax, содержание форм и возможности http-клиента «неконтролируемыми особенностями внешней среды». Я считаю вполне позволительным и допустимым то, что csrf (как и автоэкранирование в шаблонах) подразумевается включенным (а, значит, содержание форм и возможности http клиентов тоже сразу автоматически соответствуют условиям, при которых способ работает).

Случаи, когда способ может не работать:

— отключена защита от CSRF
— обработчики ajax-запросов, которые должны выполнять какие-то действия при пустых запросах, и при этом занимаются обработкой как POST, так и GET
— обработчики api-запросов, которые должны что-то делать при пустых запросах и при этом занимаются обработкой как POST, так и GET
— у пользователя не работают cookie (а, значит, авторизация и тд у него тоже не работает)

Насчет ajax api и стороннего API. В случае ajax и стороннего API unbound-формы ведь не используются обычно. Там во вьюхах и так нет 2 веток условий c созданием bound или unbound формы, поэтому там и фишка эта бессмысленна. unbound-формы нужны для показа пользователю HTML с начальными значениями. Могу представить, как формы можно использовать для отдачи начальных значений через тот же json, но это опять же, imho, очень маргинальный вариант.

Я ничего не упускаю? Тут единственный интересный вариант — это использование одной и той же вьюхи как для ajax, так и для обычной работы в ситуации, когда на клиенте js собирает запрос для отправки «вручную», а не подхватывает просто данные из формы автоматически (так csrf-токен подхватится), и при этом вообще не шлет ничего для полей, у которых пустое значение (так кто-то пишет в реальной жизни? как это вообще написать, для каждого поля ставить проверку?)

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

Конечная цель всего этого — упростить поддержку кода. И мы тут, очевидно, разошлись в оценках) Может, из-за того, что код разный имеем в виду. Мне кажется, что из-за полполпроцента случаев (которые, imho, довольно явно отличаются от обычных, и их нетрудно заметить) усложнять код почти всех вьюх (вводить дополнительный уровень вложенности и дублировать параметры конструктора) неправильно.

автоэкранирование в шаблонах, например.

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

а view-функции из другой области. они предназначены для обработки http запросов. поэтому было бы просто замечательно, если бы django предоставляла аналогичные средства, так же упрощающие поддержку семантики этого протокола (в понимании rfc2616)…

в реальности все совершенно иначе. view-фукнция является точкой входа для обработки любого запроса к данному URI. и вся мудреная логика формирования ответа целиком лежит на совести пользовательского кода (в том числе соответствие ответа типу сообщения GET, POST, PUT, ..). заморчки с диспетчеризацией данных для формы, по типу запроса, это прямое следствие джанговской архитектуры. вот решение этой задачи (на что сейчас все прикладники кладут, по понятным причинам) было бы приятно видеть на уровне фреймворка. сравните:

# первая попавшаяся под руку хрень -)
$ curl -svX PUT msdn.microsoft.com/ru-ru/default.aspx > /dev/null
(HTTP/1.1 411 Length Required)

# django
$ curl -svX PUT docs.djangoproject.com/en/1.2/ > /dev/null
(HTTP/1.0 200 OK)

впрочем, не так давно, появилась определенная надежда на class-based views, ожидаемые в следующем релизе. они могли бы предоставлять нужный функционал по умолчанию… (правда это нехилый такой лисапед — классная реализация уже давно есть в django-piston).

а csrf это вообще фича уровня протокола приложения. в contrib ей самое место. :)

в принципе, я понял Вашу точку зрения, но принять не могу. :)

Переменные в Python

В данном уроке мы рассмотрим чрезвычайно важную концепцию языка Python: переменные. Они позволят нам запоминать, переиспользовать и передавать данные в программах. Поскольку переменные можно найти в любом современном языке программирования, поэтому вам уже могут быть знакомы основные концепции. Однако я настоятельно рекомендую прочитать статью даже тем, для кого Python является не первым языком, поскольку здесь будут разобраны особености, которые не имеют аналогов в других языках.

Объявление переменных

Во первых стоит отметить что Python является языком с динамической типизацией. Это означает что любая переменная может содержать любые значение. Это отличается от тех же переменных, например, в C++. Там нужно явно указывать тип, значение которого будет содержать переменная.

Теперь давайте посмотрим как мы можем создать переменную и присвоить ей значение:

В данном примере мы создаем две переменные: foo и bar . Первая переменная содержит число, а вторая строку. Подробнее о типах в Python в следующем уроке. Как видите, для того чтобы присвоить переменной значение достаточно слева от оператора = указать ее имя, а с права ее значение. Если во время присваивания такой переменной нет, то интерпретатор Python’a создаст новую переменную с указанным именем и присвоит ей указанное значение.

Переменные в Python следует именовать в нижнем регистре и слова разделять нижним подчеркиванием: _ . Например: max_age , init_state .

После объявления переменной мы можем ее использовать в любом выражении. В нашем примере, мы передали переменную bar в функцию print() .

Вот результат работы программы:

Мы также можем указать значение для нескольких переменных за одну операцию:

Обмен значений переменных

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

Если попытаться сделать такой обмен, сначала присвоив первой переменной значение второй, а второй — значение первой, ничего не получится. Допустим, есть две переменные a и b. При этом a = 5 и b = 6 . Если выполнить выражение a = b , то переменная a будет хранить число 6, также как и b . Число 5 будет утеряно. После этого выражение b = a теряет смысл, т. к. b будет присвоено его же текущее значение. В данном случае 6.

Поэтому в программировании при обмене значений переменных обычно вводят третью переменную, играющую роль буфера (ее иногда называют буферной переменной). В этой переменной сохраняют значение первой переменной, потом первой переменной присваивают значение второй, a новое значение для второй переменной берут из буфера.

Таким образом классический алгоритм обмена значений двух переменных выглядит так:

Однако есть другой способ, позволяющий не использовать третью переменную. Но этим способом не всегда рекомендуют пользоваться. Выглядит он так:

Поскольку в Python есть такая вещь как множественное присваивание, то обмен значений переменных можно выполнить в одну строчку:

Почему такое возможно? В Питоне есть такая структура данных как кортеж.

При выполнении a , b = b , a интерпретатор Python сначала получает значения связанные с переменными b и a (правая часть) и помещает их в кортеж, в данном случае получится (10, 20). После этого он связывает каждый элемент кортежа в определенной позиции с переменной в той же позиции, но в кортеже слева (a,b) .

Таким образом можно поменять значения не только двух переменных, но и трех, четырех и т. д. Кроме того в Python можно обменять значения переменных разных типов. Такая возможность связана с тем, что тип данных в Питоне привязан не к переменной, а к значению:

Цукерберг рекомендует:  Почему они рекомендуют веб
Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих
Функция Описание