如何寫一個pyton模塊

寫好一個pyton模塊

###項目結構html

model.py 項目關鍵的類python

util.py 項目幫助文件git

api.py 開放的apigithub

main.py 項目的啓動腳本api


###0 __init__.py文件 python 的模塊是經過__init__.py文件組織,當用戶import module時,該文件自動執行。網絡

"""
XXX library
~~~~~~~~~~~~~~~~~~~~~
how to use
usage:
   >>> print "ok" 
   ok
"""

__title__ = ''
__version__ = '1.0.0'
__author__ = 'jchluo'
#__license__ = 'Apache 2.0'
#__copyright__ = ''


#import api
from .model import ToyModel 

# Set default logging handler to avoid "No handler found" warnings.
import logging
try:  # Python 2.7+
    from logging import NullHandler
except ImportError:
    class NullHandler(logging.Handler):
        def emit(self, record):
            pass

logging.getLogger(__name__).addHandler(NullHandler())

分爲四部分,分別是註釋、元數據、公開API、其餘操做。session

A 註釋

提供模塊名、描述等信息和簡單的使用樣例,以方便用戶使用。app

使用樣例應該遵循doctest包的格式,以進行自動化測試。格式是post

  • ">>> "表示輸入,注意:>>>後面的一個空格必須
  • 下一行表示期待的輸出
  • 注意:樣例必須寫在源文件、方法或者類的開頭
  • 測試的命令python -m doctest -v your_module.py

例如著名的網絡模塊requests使用樣例以下測試

"""
usage:
   >>> import requests
   >>> r = requests.get('https://www.python.org')
   >>> r.status_code
   200
   >>> 'Python is a programming language' in r.content
   True
"""
B 元數據

提供包的標題、版本號、做者等信息,若是是開源模塊,最好提供licence和copyright.

C 公開API

在這裏import你但願用戶使用的類和方法,用戶代碼經過包的名字直接訪問。

例如著名的網絡模塊requests公開的部分API以下

from .models import Request, Response, PreparedRequest
from .api import request, get, head, post, patch, put, delete, options
from .sessions import session, Session

當用戶須要使用get方法時,能夠經過

>>>import requests
>>>r = request.get("http://www.baidu.com")

代碼中requestsget方法就是經過from .api import get導進來的。 若是不在這裏import,即必須

>>>import requests.api
>>>r = request.api.get("http://www.baidu.com")

不在這裏import有不少缺點。

一、用戶使用不方便,容易出錯,經過import具體的api包來調用方法。

二、泄露了requests的具體實現。假設未來有更好的訪問網絡方式,api過期,可是requests不能刪除api模塊,由於用戶的代碼中都寫了api包,一旦刪除了,用戶代碼所有出錯。

三、用戶可能會調用api的私有方法,致使程序出錯。由於私有方法是內部使用的。

D 其餘操做

這裏提供一些loggingwarnings的配置。

咱們進行一些重要的操做時,通常經過打log的方式以進行記錄,以方便後續的分析等。

request包的底層urllib3connectionpool.py是這樣打log:

>>> import logging 
>>> log = logging.getLogger(__name__)
>>> log.warn("Get xxx ")
No handlers could be found for logger "__main__"

嘗試一下就會發現,這時會提示第4行的"No handlers"的提示。

這是由於若是沒有配置好log的handler信息,log不知道怎麼處理這個warn信息。

**通常來講,咱們但願log的配置由用戶的代碼來控制。由用戶來決定打log的格式,輸出的位置,是到文件仍是屏幕。**因此模塊包通常不對log進行配置。

模塊包須要對log進行操做,例如log.warn("xxx"),可是又不能配置log的輸出位置,因而就有上面No handler的提示。

爲了沒有上面的提示,模塊包只好給log配置了一個空handler,這個hander什麼都不作,只是佔位,由於有了hander, 因此提示就再也不出現了。同時,若是用戶配置了log,就會把這個空handler覆蓋,採用了用戶的配置。下面代碼 是模塊包配置的空handler

import logging
try:  # Python 2.7+
    from logging import NullHandler
except ImportError:
    class NullHandler(logging.Handler):
        def emit(self, record):
            pass

logging.getLogger(__name__).addHandler(NullHandler())

假設用戶本身處理log, 能夠輸入如下代碼

>>> import logging
>>> logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(levelname)s %(message)s',
                    filename='myapp.log')
>>> import requests
>>> requests.get("http://www.baidu.com")

注意:上面是用戶的代碼,不是模塊包的代碼

這時候,urlllib3的 log就打到了文件myapp.log

2015-12-19 22:07:36,032 DEBUG "GET / HTTP/1.1" 200 None

###1 類


###2 方法

相關文章
相關標籤/搜索