dir0dir1dir2mod.py
и инструкции импортирования, имеющей следующий вид:
import dir1.dir2.mod
применяются следующие правила:
• dir1 и dir2 должны содержать файл __init__.py.
• dir0, каталог-контейнер, может не содержать файл __init__.py – этот файл
будет проигнорирован, если он присутствует.
• dir0, но не dir0dir1, должен присутствовать в пути поиска модулей (то есть он должен быть домашним каталогом или присутствовать в переменной окружения PYTHONPATH и так далее).
Таким образом, структура каталогов в этом примере должна иметь следующий вид (здесь отступы указывают на вложенность каталогов):
dir0 # Каталог-контейнер в пути поиска модулей
dir1
__init__.py
dir2
__init__.py
mod.py
Файлы __init__.py могут содержать программный код на языке Python, как любые другие файлы модулей. Отчасти они являются объявлениями для интерпретатора и могут вообще ничего не содержать. Эти файлы, будучи объявлениями, предотвращают неумышленное сокрытие в каталогах с совпадающими именами истинно требуемых модулей, если они отображаются позже в списке путей поиска модулей. Без этого защитного механизма интерпретатор мог бы выбирать каталоги, которые не имеют никакого отношения к вашему программному коду, только лишь потому, что в пути поиска они появляются ранее.
В общем случае файл __init__.py предназначен для выполнения действий по инициализации пакета, создания пространства имен для каталога и реализации поведения инструкций from * (то есть from … import *), когда они используются для импортирования каталогов:
Инициализация пакета
Когда интерпретатор Python импортрирует каталог в первый раз он автоматически запускает программный код файла __init__.py этого каталога. По этой причине обычно в эти файлы помещается программный код, выполняющий действия по инициализации, необходимые для файлов в пакете.
Например, этот файл инициализации в пакете может использоваться для создания файлов с данными, открытия соединения с базой данных и так далее. Обычно файлы __init__.py не предназначены для непосредственного выполнения – они запускаются автоматически, когда выполняется первое обращение к пакету.
Инициализация пространства имен модуля
При импортировании пакетов пути к каталогам в вашем сценарии после завершения операции импортирования превращаются в настоящие иерархии вложенных объектов. Например, в предыдущем примере после завершения операции импортирования можно будет использовать выражение dir1.dir2, которое возвращает объект модуля, чье пространство имен содержит все имена, определяемые файлом __init__.py из каталога dir2. Такие файлы создают пространства имен для объектов модулей, соответствующих каталогам, в которых отсутствуют настоящие файлы модулей.
Поведение инструкции from *
В качестве дополнительной особенности, в файлах __init__.py можно использовать списки __all__, чтобы определить, что будет импортироваться из каталог
Блог на Django. Часть 1 — установка
Итак начнем с установки Python-a. Так как у меня виндовс и к тому же 8.1 будет пробовать делать все под нее. Для того чтоб скачать свежую версию я воспользовался ссылкой https://www.python.org/downloads/ и на данный момент там есть версия 3.5.1, вот ее и возьму.
Во время установки я отметил галочкой пункт Add Python 3.5 to PATH, чтобы cmd его тоже распозновала.
Вот впринципе на этом данная статья может быть закончена, далее мы рассмотрим процесс настройки с БД. Хочу попробовать на postgreSQL, но а там как получится. А вообще выбор между MySQL & PostgreSQL.
Помогите с выбором БД, пишите в комментах какой отдать предпочтения.
Так же я в гит буду выкладывать все шаги разработки или же лучше выложить вконце один готовый вариант ?
Автор: Няшный Человек
Дата публикации: 2016-03-06T10:41:00.000+02:00
Пакеты и настройка пути поиска
Так, в предыдущем примере dir0 – это имя каталога, которое требуется добавить в путь поиска модулей и которое может иметь произвольную длину и путь, с учетом специфики используемой платформы, ведущий к каталогу dir1. Вместо того, чтобы использовать ошибочный синтаксис, как показано ниже:
import C:mycodedir1dir2mod # Ошибка: недопустимый синтаксис
Добавьте путь C:mycode в переменную окружения PYTHONPATH или в файл .pth
(предполагается, что это не домашний каталог программы, поскольку в этом случае этот шаг не является необходимым) и используйте такую инструкцию:
import dir1.dir2.mod.
В сущности, записи в списке путей поиска модулей содержат платформозависимые пути к каталогам, которые ведут к самым левым именам в цепочках, Основы операции импортирования пакетов представленных в инструкциях import, а сами инструкции import содержат окончание пути к каталогам платформонезависимым способом.
Автор: Няшный Человек
Дата публикации: 2016-03-03T11:44:00.000+02:00
pytest продолжение
В личных беседах и по почте поступил ряд вопросов и предложений, поэтому продолжению быть. В этой и последующих статьях погрузимся глубже в возможности pytest. Новый материал предлагаю выкладывать в виде поваренной книги — проблема, рецептура, ингредиенты, 5 минут готовки, наслаждение.
Последовательно выполнение тестовых сценариев
В тестировании часто бывают случаи, когда необходимо объединить несколько проверок в один большой тест и выполнить их последовательно. Причем бывает и так, что один сценарий зависит от результатов работы предыдущего (но такое лучше стараться избегать в автотестировании).
В следующих статьях мы посмотрим как можно избежать этой ситуации пользуясь стандартными средствами пайтеста.
Например, тестируемая программа при первом запуске накатывает схему базы (sqlite чтобы не морочиться) и заполняет её некоторой служебной информацией. Допустим перед нами стоит задача «дешево» протестировать этот модуль. Сходу задачу модно разбить на 2 подзадачи — проверка создания файла базы, затем проверка схемы и в конце проверка данных.
Самый простой вариант — нумерация в названии тестов
# conftest.py
import os
import pytest
import sqlite3
def pytest_configure(config):
config.DB_PATH = «db.sqlite»
@pytest.fixture(scope=»module»)
def creator(request):
DB_PATH = request.config.DB_PATH
con = sqlite3.connect(DB_PATH)
cur = con.cursor()
cur.executescript(«»»
create table person(
firstname,
lastname,
age
);
create table book(
title,
author,
published
);
insert into book(title, author, published)
values (
'Dirk Gently''s Holistic Detective Agency',
'Douglas Adams',
1987
);
«»»)
con.commit()
con.close()
return DB_PATH
@pytest.fixture
def cursor(request):
class cursor:
def __init__(self, dbpath):
self.dbpath = dbpath
self.conn = sqlite3.connect(self.dbpath)
def table_exists(self, table):
cursor = self.conn.cursor()
cursor.execute(
«SELECT name FROM sqlite_master WHERE type = «table»»)
tables = cursor.fetchall()
for each in tables:
if table in each:
return True
return False
def getrows(self, table):
cursor = self.conn.cursor()
cursor.execute(«SELECT * FROM %s;» % (table))
return cursor.fetchall()
return cursor(request.config.DB_PATH)
# test.py
def test_1_db_exists(creator):
assert os.path.exists(creator)
@pytest.mark.parametrize(«table», [«person», «book»])
def test_2_check_scheme(table, creator, cursor):
result = cursor.table_exists(table)
assert result
@pytest.mark.parametrize(«table», [«book»])
def test_3_check_rows(table, creator, cursor):
assert cursor.getrows(table)
Спасибо документации питона за готовые примеры.
У такого подхода есть ряд недостатков.
1. В названии теста появляется нумерация — это лишняя мета информация. (Это может сказаться на тестовом отчете или билд логе CI сервера)
2. Название теста усложняется
3. Вставка нового элемента в середину приведет к смене нумерации всех последующих тестов
Вариант посложнее — маркеры
Свои маркеры мы реализовывать не будем, а используем готовый плагин pytest-ordering. В принципе вся реализация такого плагина составит не больше 100 строчек кода.
# test.py
@pytest.mark.order1
def test_db_exists(creator):
assert os.path.exists(creator)
@pytest.mark.order2
@pytest.mark.parametrize(«table», [«person», «book»])
def test_check_scheme(table, creator, cursor):
result = cursor.table_exists(table)
assert result
@pytest.mark.order3
@pytest.mark.parametrize(«table», [«book»])
def test_check_rows(table, creator, cursor):
assert cursor.getrows(table)
Наши тестовые функции преобразились, стали более понимаемы для чтения.
Из коробки плагин содержит создание цепочек выполнения, более понятные маркеры (pytest.mark.run('first'), pytest.mark.run('second')) и прочее. Более подробно в микро доку плагина.
Ссылки
[1] https://docs.python.org/2/library/sqlite3.html
[2] http://pytest-ordering.readthedocs.org/en/develop/
Автор: Евгений Курочкин
{} vs dict()
В питоне предусмотрена возможность создать словарь двумя способами — через фигурные скобки {} и через конструктор dict(). В чем разница и что лучше использовать в коде?
Код
a = dict(one=1, two=2, three=3)
b = {'one': 1, 'two': 2, 'three': 3}
Пример наглядно демонстрирует что при статическом определении атрибутов количество кода практически одинаковое (скобки больше всего лишь на 2 символа).
Инициализация
Конструктор словаря предлагает расширенный функционал для инициализации словаря.
d = dict((str(v),v) for v in range(10))
dict(zip(['one', 'two', 'three'], [1, 2, 3]))
Скорость работы
Выполним в консоли следующие выражения
>>python -m timeit «{}»
10000000 loops, best of 3: 0.034 usec per loop
>>python -m timeit «dict()»
10000000 loops, best of 3: 0.127 usec per loop
Почему такая существенная разница в скорости? Все просто, смотрим что выдает диассемблер
>>import dis
>>def d(): t = {}
>>dis.dis(d)
1 0 BUILD_MAP 0
3 STORE_FAST 0 (t)
6 LOAD_CONST 0 (None)
9 RETURN_VALUE
>>def d(): t = dict()
>>dis.dis(d)
1 0 LOAD_GLOBAL 0 (dict)
3 CALL_FUNCTION 0
6 STORE_FAST 0 (t)
9 LOAD_CONST 0 (None)
12 RETURN_VALUE
При вызове конструктора dict() выполняется большее количество инструкций питона.
Вывод
Если для словаря заранее известны пары ключ-словарь, то в коде лучше использовать фигурные скобки, т.к. они дают некоторый прирост скорости при создании словаря. При динамическом создании словаря придется использовать конструктор.
PS. Все выводы актуальны и для списков
Ссылки
https://docs.python.org/2/library/stdtypes.html#mapping-types-dict
http://stackoverflow.com/questions/6610606/dict-literal-vs-dict-constructor-any-preferred
Автор: Евгений Курочкин
Топ 10 вопросов по python на stackoverflow
What does the yield keyword do in Python?
What is a metaclass in Python?
How to check whether a file exists using Python
Does Python have a ternary conditional operator?
Calling an external command in Python
How can I make a chain of function decorators in Python?
What does `if __name__ == “__main__”:` do?
How can I merge two Python dictionaries in a single expression?
Sort a Python dictionary by value
How do I install pip on Windows?
Довольно ожидаемо
Автор: Евгений Курочкин
