如何写一个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 方法

相关文章
相关标签/搜索