亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何組織 Python API 模塊使其整潔?

如何組織 Python API 模塊使其整潔?

慕姐8265434 2022-06-07 19:46:17
我正在編寫一個代表一些 Web API 的 Python 庫?,F在,我的庫目錄看起來接近這個:__init__.pyAccount.pyOrder.pyCategory.pyrequests.py在__init__.py,我有這樣的事情:from .Account import Accountfrom .Order import Orderfrom .Category import Categoryfrom . import requests這允許使用import cool_site然后cool_site.Account(…)等等,但它有以下問題:當我在 IDLE 中玩弄我的代碼時,對象然后被調用cool_site.Account.Account,我覺得這很糟糕。1.有什么辦法可以避免類名重復,并且每個類都有單獨的文件嗎?下一件我感覺不太好的事情是我的代碼組織?,F在,我的Account班級在初始化時獲取憑據,創建一個requests.Session對象,然后處理與服務器的所有通信,即搜索訂單等。然后,此類Account實例會將自身傳遞給所有其他實例,例如傳遞給Order- 因此訂單的實例將具有.account保存Account創建它的實例的屬性。當另一個類實例本身必須做某事時,例如更改訂單的注釋(通過調用o.comment = 'new comment',因此通過類@comment.setter中的裝飾器Order),它會將其轉發給在初始化時傳遞給它的 Account 對象,然后使用 example self.account.set_order_comment(new_comment)。然后,此方法將使用所有 Web 請求來實現該目標。2. 將服務器通信邏輯放在一個類中更好還是將其不同方面分散到受它們影響的類中更好?我想問的最后一件事是如何以及在何處保留低級請求模板?,F在我在cool_site.requests子模塊中有它,并且對于不同的請求有不同的功能,例如SetOrderComment對于上面提到的情況(它是一個函數,所以它應該是小寫的,但在這種情況下,我認為它在某種程度上類似于一個類 - 是可以嗎?)。將Account.set_order_comment像這樣使用它:r = cool_site.requests.SetOrderComment(order.id, new_comment)response = self._session.request(**r)Session.request因為這個函數從requests庫返回一個帶有參數的字典。身份驗證標頭已在類實例的_session屬性中設置。Account我覺得它有點難看,但我沒有更好的主意。3.如何組織網絡請求以保持一切干凈?后文很抱歉這個問題太長了,涵蓋了 API 庫設計的許多方面,但所有的提示都將不勝感激。在某種程度上,以上三個問題都可以表達為“如何做得更好、更清潔?” 或“大多數 Python 開發人員是如何做到的?”,甚至可能是“最 Pythonic 的感覺是什么?”。把你能想到的任何小技巧都扔給我。
查看完整描述

3 回答

?
慕尼黑5688855

TA貢獻1848條經驗 獲得超2個贊

我可以提出一個簡單的提示:您可以__all__ = ["Account"]Account.py模塊中使用,然后from .Account import *__init__.py文件中使用。我相信這解決了你的第一個問題。你可以在這里閱讀__all__魔術方法。簡而言之,您可以指定使用時要導入的方法等。您可以隱藏“私有”方法以防止使用.from x import *_one_leading_underscore



查看完整回答
反對 回復 2022-06-07
?
青春有我

TA貢獻1784條經驗 獲得超8個贊

我最近一直在考慮非常相似的事情wistiapy。我目前對客戶端代碼組織的思考的例子就在里面。YMMV。

  1. “每個文件一個類”比 Python 更像是一種 Java 風格指南。Python 模塊是代碼層次結構中合法且重要的級別,您不必擔心同一模塊中有多個函數或類。您可以將所有模型類放在一個.models模塊中,然后from .models import (Account, Order, Category)__init__.py.

  2. 客戶端庫的或多或少的常見做法似乎是有一個client模塊,包含類似MyServiceClient類的東西。(例如Segment 客戶端)。這就是網絡邏輯的所在。如果您想讓公共接口成為模塊級函數,您可以通過創建默認客戶端并讓函數調用其方法來做一些聰明的事情。

函數應該是snake_case,類應該是PascalCase。做任何其他事情往往會導致更多的混亂而不是好處。

您正在處理的一個大問題似乎是試圖在“Active Record”模式(some_account.set_order_comment(comment))和“Data Mapper”模式(set_order_comment(account, comment))之間進行選擇。兩者都可以,它們各有優缺點。我發現數據映射器模式——使用智能函數來操作相當簡單的數據類——更容易開始。

我發現同時設計公共接口和使用該接口的東西很有幫助。在調用代碼中,您可以編寫您想調用的內容,然后“由外向內”實現客戶端代碼。


查看完整回答
反對 回復 2022-06-07
?
MYYA

TA貢獻1868條經驗 獲得超4個贊

1).py 文件的名稱中沒有大寫(也盡量避免_)所以你的文件應該是


__init__.py

account.py

order.py

category.py

requests.py

2)如果你想使用cool_site.Account你需要添加到__init__.py


from .account import Account

from .order import Order

from .category import Category


__all__ = [

    'Account',

    'Order',

    'Category',

]

3)SetOrderComment是壞名聲,使用set_order_comment


4)如果您編寫一個用于與 API 通信的 python 包裝器,請創建在每個 API 請求中執行授權和其他相同內容的方法。此方法應將請求 kwargs 的一部分作為參數,這些 kwargs 對于不同的 API 調用是不同的


例如


class API:

    def __init__(self, endpoint:s str, api_key: str):

        self.endpoint = endpoint

        self.api_key = api_key


    def _get_auth_headers(self) -> Dict[str, str]:

        return {

           'Authorization': 'Bearer ' + self.api_key,

        }


    def get(self, path, params)

         resp = requester.get(

            self.endpoint + path,

            headers=self._get_auth_headers(),

            params=params,

            timeout=30,

        )

        self._check_api_response(resp)

        payload = resp.json()

        return payload

5) 如果您編寫 python API,請查看flask 和 django 框架以及帶有 API 編寫的項目。你應該在那里找到一些好主意。


查看完整回答
反對 回復 2022-06-07
  • 3 回答
  • 0 關注
  • 227 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號