Успешный
Open Source
Андрей Светлов
О себе
● 15 лет использования Python
● Python Core Developer
● Соавтор нескольких библиотек (asyncio,
aiohttp, aiozmq, aiopg)
● andrew.svetlov@gmail.com
● http://asvetlov.blogspot.com
Writing Open Source Library
Код на github
Этого явно недостаточно
Публичность
● Не знают — не используют.
● Статьи, блоги, stackoverflow и т.д.
● Не жалейте время на bug tracker
Документация
● Шанс составить первое впечатление
● Английский
● Docstrings и README.rst — недостаточно
● Нарративность
● Примеры
● readthedocs.org
Тесты
● Читаемые и хорошо организованные
● Полные
● coverage.py
● Как минимум 95% покрытие
● Continuous Integration (travis-ci.org)
Код
● pep8 — обязательно
● VCS (гитхаб прекрасен)
● Версии продукта
● Ветки, тэги, релизы
● Примеры использования
Инфраструктура
● setup.py
● PyPI
● readthedocs
● travis-ci
● инструкция по установке
Ясность
Хорошая библиотека — простая библиотека
Pubic и Private API
class A:
def __init__(self, param):
self.param = param
def public(self):
return self.private()
def private(self):
return self.param * 2
class A:
def __init__(self, param):
self._param = param
def public(self):
return self._private()
def _private(self):
return self._param * 2
Public API
● по умолчанию всё "закрыть".
● открывать только то что сознательно
желаем сделать открытым
● Не нужно бояться "закрытых" классов
Docstrings
class A:
def __init__(self, param):
self._param = param
def public(self):
return self._private()
def _private(self):
"""Private function"""
return self._param * 2
class A:
"""Docstring for class"""
def __init__(self, param):
self._param = param
def public(self):
"""This is public"""
return self._private()
def _private(self):
# Private function
return self._param * 2
Понятное API
Если нелегко написать документацию — API
плохое
Хорошие имена
twisted.internet.defer.
Deferred
Twised's Deferred
does something —
OMG!
asyncio.Future
Трудность выбора имен
ZeroMQ Req/Rep, Push/Pull и Pub/Sub
Requester? Pusher???
RPC Извещения Подписка
Клиент Req Push Pub
Сервер Rep Pull Sub
Решение
connect_rpc — RPCClient
serve_rpc — RPCServer
connect_pipeline — PipelineClient
serve_pipeline — PipelineServer
connect_pubsub — PubSubClient
serve_pubsub — PubSubServer
Наследование
class Base:
def do_work(self):
self.handle('param')
class Derived(Base):
def handle(self, param):
do_something()
class Base(metaclass=abc.ABCMeta):
def do_work(self):
self.handle('param')
@abc.abstractmethod
def handle(self, param):
pass
class Derived(Base):
def handle(self, param):
do_something()
Агрегация лучше наследования
class Service:
def do_work(self):
self.log('operaion')
def log(self, param):
pass
class SocketLoggerMixin:
def log(self, param):
self.socket.send(param)
class SocketLoggingService(
SocketLoggerMixin, Service):
pass
class Service:
def __init__(self, logger):
self._logger = logger
def do_work(self):
self._logger.log('operaion')
class Logger:
def log(self, param):
pass
Естественная полнота API
class Subscriber:
def subscribe(self, name):
pass
class Subscriber:
def subscribe(self, name):
pass
def unsubscribe(self, name):
pass
@property
def subscriptions(sef):
pass
Предметная область
Матрицы
a * b
a @ b
a + b
len(a)
Устоявшиеся соглашения
class Point:
def __init__(self, a, b):
self.a, self.b = a, b
def __add__(self, other):
self.a += other.a
self.b += other.b
return self
class Point:
def __init__(self, x, y):
self._x, self._y = x, y
x = property(lambda self: self._x)
y = property(lambda self: self._y)
def __add__(self, other):
return Point(self._x + other.
_x,
self._y + other.
_y)
Магические методы
def __eq__(self, other):
if isinstance(other, Point):
return self._x == other._x and self._y == other._y
else:
return NotImplented
def __ne__(self, other):
return not self == other
def __hash__(self):
return (self._x, self._y)
Коллекции
class ReadonlyDict(collections.abc.Mapping):
def __init__(self, dct):
self._dct = dct
def __len__(self):
return len(self._dct)
def __iter__(self):
return iter(self._dct)
def __getitem__(self, key):
return self._dct[key]
assert set(ReadonlyDict({'a': 1, 'b': 2}).keys()) == set('a', 'b')
Неудачный пример
sqlalchemy.engine.result.RowProxy
Это, хмм, abc.Sequence
len(result_proxy)
'column_name' in result_proxy
result_proxy[0]
result_proxy['column_name']
result_proxy[1: 5]
result_proxy1 < result_proxy2
iter(result_proxy)
Исключения
def login(login, passwd):
res = db.execute(
"SELECT * FROM users "
"WHERE login = %s", login)
return res['passwd'] == passwd
def login(login, passwd):
try:
res = db.execute(
"SELECT * FROM users "
"WHERE login = %s", login)
if res['passwd'] != passwd:
raise CannotLogin()
except DatabaseNotFoundError as ex:
raise CannotLogin() from ex
Singletons
Просто зло.
Я их не использую.
Логирование
logging.getLogger('').info('log message')
Настраивание объема сообщений в лог
production != dev environment
библиотека != приложение пользователя
Проверка параметров
def write(self, data):
if not isinstance(data, (bytes, bytearray, memoryview)):
raise TypeError('data argument must be byte-ish (%r)',
type(data))
if server_side:
if not sslcontext:
raise ValueError('Server side ssl needs a valid SSLContext')
библиотека != приложение
● Обратная совместимость
● Внимание к деталям
● Простота и понятность
● Документация
Вопросы?
andrew.svetlov@gmail.com

More Related Content

PDF
PostSharp - Threading Model
PPTX
PostSharp - Threading Model Library
PPT
Надежда Серкова -- Автоматическая генерация Perl скриптов для тестирования си...
PDF
Rust: история языка и контекст применения
PDF
Нескучное тестирование с pytest
PDF
Кроссплатформенная разработка на Haxe
PDF
Курс Java-2016. Занятие 06. Файлы и ввод-вывод
PPTX
Система обработки бизнес-логики server-side приложения на Groovy
PostSharp - Threading Model
PostSharp - Threading Model Library
Надежда Серкова -- Автоматическая генерация Perl скриптов для тестирования си...
Rust: история языка и контекст применения
Нескучное тестирование с pytest
Кроссплатформенная разработка на Haxe
Курс Java-2016. Занятие 06. Файлы и ввод-вывод
Система обработки бизнес-логики server-side приложения на Groovy

What's hot (20)

PDF
REPL в Node.js: улучшаем быт разработчик
PDF
Flask как хорошее решение для веб проекта
ODP
Скриптовой язык Groovy и его применение в рамках разработки ПО
PPTX
Автоматизация и Selenium IDE
PPT
Белым по черному или альтернативное использование unit-тестирования
PDF
TeaVM: dead code elimination and devirtualization
PPTX
Django: инструкция по применению
PPTX
Андрей Зайцев - TDD в кровавом энтерпрайзе
PPTX
JavaScript: хороший тон клиентской разработки
PDF
Easy selenium test automation on python
PDF
Визуализация покрытия автоматизированными UI тестами
PPTX
курс Java 2016. занятие 03. интерфейсы, generic, исключения
PPTX
автоматизация тестирования с помощью Selenium
PPTX
Postman тестирование api v1.0 (1)
PPTX
разработка бизнес приложений (8)
PDF
JPoint 2016 - Etudes of DIY Java profiler
PDF
Про асинхронное сетевое программирование
PPTX
Грязная автоматизация
PPT
презентация л.р. №1
REPL в Node.js: улучшаем быт разработчик
Flask как хорошее решение для веб проекта
Скриптовой язык Groovy и его применение в рамках разработки ПО
Автоматизация и Selenium IDE
Белым по черному или альтернативное использование unit-тестирования
TeaVM: dead code elimination and devirtualization
Django: инструкция по применению
Андрей Зайцев - TDD в кровавом энтерпрайзе
JavaScript: хороший тон клиентской разработки
Easy selenium test automation on python
Визуализация покрытия автоматизированными UI тестами
курс Java 2016. занятие 03. интерфейсы, generic, исключения
автоматизация тестирования с помощью Selenium
Postman тестирование api v1.0 (1)
разработка бизнес приложений (8)
JPoint 2016 - Etudes of DIY Java profiler
Про асинхронное сетевое программирование
Грязная автоматизация
презентация л.р. №1
Ad

Similar to Writing Open Source Library (20)

PDF
C++ STL & Qt. Занятие 11.
ODP
About Python
PDF
django cheBit'11
 
PPT
бегун
PPT
бегун
PDF
Виталий Каторгин, Wamba
PPT
Rich UI on Dojo Toolkit and Zend Framework
PDF
Web осень 2013 лекция 6
PPTX
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
PPT
Декораторы в Python и их практическое использование
PPTX
Tdd php
PPTX
Тестирование Web API
ODP
Системное тестирование приложений на Ruby on Rails с применением Rspec и Cap...
ODP
Alexander Dymo - IT Jam 2009 - Ruby: Beaty Or The Beast
PDF
20160303 Hacking PostgreSQL Тема 02 Сообщество PostgreSQL и инструменты разра...
PDF
Как мы делаем модули PHP в Badoo – Антон Довгаль
PDF
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
PPTX
Node.js введение в технологию, КПИ #ITmeetingKPI
PPT
Платформа для автоматического тестирования Erlang проектов на примере UserGat...
C++ STL & Qt. Занятие 11.
About Python
django cheBit'11
 
бегун
бегун
Виталий Каторгин, Wamba
Rich UI on Dojo Toolkit and Zend Framework
Web осень 2013 лекция 6
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
Декораторы в Python и их практическое использование
Tdd php
Тестирование Web API
Системное тестирование приложений на Ruby on Rails с применением Rspec и Cap...
Alexander Dymo - IT Jam 2009 - Ruby: Beaty Or The Beast
20160303 Hacking PostgreSQL Тема 02 Сообщество PostgreSQL и инструменты разра...
Как мы делаем модули PHP в Badoo – Антон Довгаль
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
Node.js введение в технологию, КПИ #ITmeetingKPI
Платформа для автоматического тестирования Erlang проектов на примере UserGat...
Ad

More from Andrew Svetlov (6)

PDF
ODP
PDF
Интерфейсы в Python
Интерфейсы в Python

Writing Open Source Library