Как организовать модуль Python API, чтобы сделать его аккуратным? - PullRequest
1 голос
/ 27 сентября 2019

Я пишу библиотеку Python, которая представляет некоторый веб-API.Прямо сейчас каталог моей библиотеки выглядит примерно так:

  • __init__.py
  • Account.py
  • Order.py
  • Category.py
  • requests.py

В __init__.py у меня есть что-то вроде этого:

from .Account import Account
from .Order import Order
from .Category import Category
from . import requests

Это позволяет использовать import cool_site, а затем cool_site.Account(…)и так далее, но у него есть следующая проблема: когда я играю со своим кодом в IDLE, объект тогда называется cool_site.Account.Account, что я считаю плохим.

1.Есть ли способ избежать дублирования имен классов и при этом иметь отдельный файл для каждого класса?

Следующее, что меня не устраивает, это моя организация кода.Прямо сейчас мой класс Account принимает учетные данные при инициализации, создает объект requests.Session, а затем обрабатывает все коммуникации с сервером, то есть поиск заказов и так далее.Этот экземпляр класса Account затем передаст себя всем другим экземплярам, ​​например, Order, поэтому экземпляр заказа будет иметь свойство .account, содержащее экземпляр Account, который его создал.Когда сам другой экземпляр класса должен что-то сделать, например, изменить комментарий к заказу (вызывая o.comment = 'new comment', то есть с помощью @comment.setter декоратора в классе Order), он перенаправляет его в объект Account, который передается емуинициализация, а затем использует, например, self.account.set_order_comment(new_comment).Затем этот метод будет использовать все веб-запросы для достижения этой цели.

2.Лучше ли хранить логику взаимодействия с сервером в одном классе или распространять различные ее аспекты на классы, на которые они влияют?

Последнее, о чем я хотел бы спросить, - как и где поддерживать низкий уровень.шаблоны запросов уровня.Прямо сейчас у меня это есть в cool_site.requests субмодуле, и есть разные функции для разных запросов, например SetOrderComment для случая, упомянутого выше (это функция, поэтому она должна быть в нижнем регистре, но в этом случае я думаю, что это похоже накласс в некотором роде - это нормально?).Account.set_order_comment будет использовать его следующим образом:

r = cool_site.requests.SetOrderComment(order.id, new_comment)
response = self._session.request(**r)

, потому что эта функция возвращает dict с аргументами функции Session.request из библиотеки requests.Заголовки аутентификации уже установлены в свойстве _session экземпляра класса Account.Я чувствую, что это немного уродливо, но у меня нет идеи получше.

3.Как организовать веб-запросы, чтобы сохранить все это в чистоте?

Post scriptum

Извините, этот вопрос очень длинный и охватывает многие аспекты проектирования библиотеки API, новсе советы будут оценены.В некотором смысле, все три вопроса выше могут быть выражены как «Как сделать это лучше и чище?»или «Как большинство разработчиков Python делают это?», или, может быть, даже «Что бы вы чувствовали больше всего Pythonic?».

Дайте мне несколько маленьких советов, которые вы можете придумать.

...