https://api.travis-ci.org/chinapnr/fishbase.svg?branch=master https://readthedocs.org/projects/fishbase/badge/?version=latest https://coveralls.io/repos/github/chinapnr/fishbase/badge.svg?branch=master

fishbase 函数库使用说明

fishbase 是我们自己开发和整理的一套 Python 基础函数库。 从这几年的 Python 开发中抽象了很多常见的通用的业务逻辑,以希望减少日常开发中的一些重复的工作量。

我们从2016年左右逐渐开始用 Python 开发一些项目,还不能算很有经验,但是也经常碰到一些问题, fishbase 库并不是用来解决很复杂的问题,并且有些是对系统函数的进一步封装,以简化应用程序开发中的工作量和引用的复杂度。

目前,我们正在加快 fishbase 库的建设,包括完善文档和加入单元测试、示例代码、文档等。希望能够帮助到所有的 Python 爱好者和应用开发人员。

更新记录

2018.5.30 v1.0.13

2018.5.21 v1.0.12

  • 19035, rename package ‘fish_base’ to ‘fishbase’

2018.5.18 v1.0.11

  • 19011, 从19011开始编号,ok
  • 19015, common conf_as_dict() 增加 docstring 说明, ok
  • 19016, 开始测试使用 sphinx 来组织 api 说明文档,ok
  • 19017, 将 conf_as_dict() 说明加入到 doc 中,ok
  • 19018, __init__.py 中的 get_ver() 返回版本号功能简化,ok
  • 19019, common class SingleTon() 增加 docstring 说明,ok
  • 19020, csv csv_file_to_list() 增加 docstring 说明,ok
  • 19021, common 重新声明为 fish_common, csv 重新生命为 fish_csv, 所有包带 fish 前缀,ok
  • 19022, sphinx doc 的 theme 修改为 rtd theme,https://sphinx-rtd-theme.readthedocs.io/en/latest/ , ok
  • 19023, logger set_log_file() 增加 docstring 说明,ok
  • 19024, fish_file 函数加入 docstring 说明,ok
  • 19025, common, 去除 get_md5() 函数,ok
  • 19026, common, 增加 class GetMD5,增加字符串、小文件、大文件三种类型的 md5计算,ok
  • 19027, test, 修改原来的 unittest 部分,完善对于 common 函数的单元测试,ok
  • 19028, common, conf_as_dict() 逻辑修改,更加严密,ok
  • 19029, common, 增加 json_contained() 函数,判断两个 json 是否有包含关系,ok
  • 19030, common, 增加 splice_url_params() 函数;ok
  • 19031, 项目,增加 requirements.txt; ok
  • 19032, 项目,增加 .travis.yml, 支持持续集成测试; ok
  • 19033, 项目,增加对于 coveralls.io 的支持,监视 ut 的覆盖率; 本地 python 2.7.15 测试通过; ok
  • 19034, 项目,修改 __init__.py 和 setup.py 中对于 __version__ 的用法; ok

2018.3.20 v1.0.10

  • 19006, 增加,get_time_uuid(), 获得带时间戳的流水号;ok
  • 19007, 增加,if_any_elements_is_space(), 判断参数列表是否存在 None 或空字符串或空格字符串;ok
  • 19008, common,增加 conf_as_dict(),读入配置文件,返回根据配置文件内容生成的字典类型变量; ok
  • 11001, 整体结构和开发方法调整;
  • 11002, 增加 csv 功能模块,增加函数 csv_file_to_list(); ok
  • 11003, fish_file 模块修改为 file,目前向下兼容保留 fish_file; ok
  • 11004, file 模块的 get_abs_filename_with_sub_path() 修改;ok
  • 11005, fish_date 模块修改为 date, demo/demo_date.py 演示用法;ok
  • 11006, 安装包的安装程序 setup.py 中 setup.py 引入源的修改;ok
  • 11007, pip 安装时候支持自动安装 python-dateutil 包; ok
  • 11008, check_platform() 归入到 system 包
  • 11009, csv, csv_file_to_list() 函数增加过滤空行功能;ok
  • 11010, logger, log 相关代码优化简化; ok
  • 11011, demo, 将原来 test 下的 test log 程序移动到 demo 路径下; ok
  • 11013, demo, common.conf_as_dict() 的 demo 例子完善;ok
  • 11014, common, conf_as_dict() 增加返回内容,字典长度;ok
  • 11015, common 增加 class SingleTon,单例的基础类;ok

API 函数列表

可以到以下单元中查找具体的函数列表和使用说明。

fish_common 基本函数包

fish_common.conf_as_dict(conf_filename) 读入 ini 配置文件,返回根据配置文件内容生成的字典类型变量;
fish_common.get_uuid(kind) 获得不重复的 uuid,可以是包含时间戳的 uuid,也可以是完全随机的;基于 Python 的 uuid 类进行封装和扩展;
fish_common.GetMD5.string(s) 获取一个字符串的MD5值
fish_common.GetMD5.file(filename) 获取一个文件的 MD5 值
fish_common.GetMD5.big_file(filename) 获取一个大文件的 MD5 值
fish_common.if_json_contain(left_json, …) 判断一个 json 是否包含另外一个 json 的 key,并且 value 相等;
fish_common.SingleTon 申明一个单例类,可以作为需要单例类时候申明用的父类
fish_common.sorted_list_from_dict(p_dict[, …]) 根据字典的 value 进行排序,并以列表形式返回
fish_common.splice_url_params(dic) 根据传入的键值对,拼接 url 后面 ? 的参数,比如 ?key1=value1&key2=value2

fish_common 包含的是最常用用的一些函数和类。

class fish_common.GetMD5

计算普通字符串和一般的文件,对于大文件采取逐步读入的方式,也可以快速计算;基于 Python 的 hashlib.md5() 进行封装和扩展;

举例如下:

print('--- md5 demo ---')
print('string md5:', GetMD5.string('hello world!'))
print('file md5:', GetMD5.file(get_abs_filename_with_sub_path('test_conf', 'test_conf.ini')[1]))
print('big file md5:', GetMD5.big_file(get_abs_filename_with_sub_path('test_conf', 'test_conf.ini')[1]))
print('---')

执行结果:

string md5: fc3ff98e8c6a0d3087d515c0473f8677
file md5: fb7528c9778b2377e30b0f7e4c26fef0
big file md5: fb7528c9778b2377e30b0f7e4c26fef0
static big_file(filename)

获取一个大文件的 MD5 值

Param:
  • (string) filename 需要进行 hash 的大文件路径
Returns:

  • (string) result 32位小写 MD5 值

static file(filename)

获取一个文件的 MD5 值

Param:
  • (string) filename 需要进行 hash 的文件名
Returns:

  • (string) result 32位小写 MD5 值

static string(s)

获取一个字符串的MD5值

Param:
  • (string) str 需要进行 hash 的字符串
Returns:

  • (string) result 32位小写 MD5 值

class fish_common.SingleTon

申明一个单例类,可以作为需要单例类时候申明用的父类

Param:
Returns:

举例如下:

print('--- class singleton demo ---')
t1 = SingleTon()
t1.x = 2
print('t1.x:', t1.x)

t2 = SingleTon()

t1.x += 1

print('t1.x:', t1.x)
print('t2.x:', t2.x)
print('---')

执行结果:

--- class singleton demo ---
t1.x: 2
t1.x: 3
t2.x: 3
---
fish_common.conf_as_dict(conf_filename)

读入 ini 配置文件,返回根据配置文件内容生成的字典类型变量;

Param:
  • conf_filename: (string) 需要读入的 ini 配置文件长文件名
Returns:

  • flag: (bool) 读取配置文件是否正确,正确返回 True,错误返回 False
  • d: (dict) 如果读取配置文件正确返回的包含配置文件内容的字典
  • count: (int) 读取到的配置文件有多少个 key 的数量

举例如下:

print('--- conf_as_dict demo---')
# 定义配置文件名
conf_filename = 'test_conf.ini'
# 读取配置文件
ds = conf_as_dict(conf_filename)
# 显示是否成功,所有 dict 的内容,dict 的 key 数量
print('flag:', ds[0])
print('dict:', ds[1])
print('length:', ds[2])

d = ds[1]

# 显示一个 section 下的所有内容
print('section show_opt:', d['show_opt'])
# 显示一个 section 下面的 key 的 value 内容
print('section show_opt, key short_opt:', d['show_opt']['short_opt'])

# 读取一个复杂的section,先读出 key 中的 count 内容,再遍历每个 key 的 value
i = int(d['get_extra_rules']['erule_count'])
print('section get_extra_rules, key erule_count:', i)
for j in range(i):
    print('section get_extra_rules, key erule_type:', d['get_extra_rules']['erule_'+str(j)])
print('---')

执行结果:

--- conf_as_dict demo---
flag: True
dict: (omit)
length: 7
section show_opt: {'short_opt': 'b:d:v:p:f:', 'long_opt': 'region=,prov=,mer_id=,mer_short_name=,web_status='}
section show_opt, key short_opt: b:d:v:p:f:
section get_extra_rules, key erule_count: 2
section get_extra_rules, key erule_type: extra_rule_1
section get_extra_rules, key erule_type: extra_rule_2
---
fish_common.get_time_uuid()

获得不重复的 uuid,可以是包含时间戳的 uuid,也可以是完全随机的;基于 Python 的 uuid 类进行封装和扩展;

支持 get_time_uuid() 这样的写法,不需要参数,也可以表示生成包含时间戳的 uuid,兼容 v1.0.12 以及之前版本;

Param:
  • kind: (int) uuid 类型,整形常量 udTime 表示基于时间戳, udRandom 表示完全随机
Returns:

  • result: (string) 返回类似 66b438e3-200d-4fe3-8c9e-2bc431bb3000 的 uuid

举例如下:

print('--- uuid demo ---')
# 获得带时间戳的uuid
for i in range(2):
    print(get_uuid(udTime))

print('---')

# 时间戳 uuid 的简单写法,兼容之前版本
for i in range(2):
    print(get_time_uuid())

print('---')

# 获得随机的uuid
for i in range(2):
    print(get_uuid(udRandom))

print('---')

执行结果:

--- uuid demo ---
c8aa92cc-60ef-11e8-aa87-acbf52d15413
c8ab7194-60ef-11e8-b7bd-acbf52d15413
---
c8ab7368-60ef-11e8-996c-acbf52d15413
c8ab741e-60ef-11e8-959d-acbf52d15413
---
8e108777-26a1-42d6-9c4c-a0c029423eb0
8175a81a-f346-46af-9659-077ad52e3e8f
---
fish_common.get_uuid(kind)

获得不重复的 uuid,可以是包含时间戳的 uuid,也可以是完全随机的;基于 Python 的 uuid 类进行封装和扩展;

支持 get_time_uuid() 这样的写法,不需要参数,也可以表示生成包含时间戳的 uuid,兼容 v1.0.12 以及之前版本;

Param:
  • kind: (int) uuid 类型,整形常量 udTime 表示基于时间戳, udRandom 表示完全随机
Returns:

  • result: (string) 返回类似 66b438e3-200d-4fe3-8c9e-2bc431bb3000 的 uuid

举例如下:

print('--- uuid demo ---')
# 获得带时间戳的uuid
for i in range(2):
    print(get_uuid(udTime))

print('---')

# 时间戳 uuid 的简单写法,兼容之前版本
for i in range(2):
    print(get_time_uuid())

print('---')

# 获得随机的uuid
for i in range(2):
    print(get_uuid(udRandom))

print('---')

执行结果:

--- uuid demo ---
c8aa92cc-60ef-11e8-aa87-acbf52d15413
c8ab7194-60ef-11e8-b7bd-acbf52d15413
---
c8ab7368-60ef-11e8-996c-acbf52d15413
c8ab741e-60ef-11e8-959d-acbf52d15413
---
8e108777-26a1-42d6-9c4c-a0c029423eb0
8175a81a-f346-46af-9659-077ad52e3e8f
---
fish_common.if_json_contain(left_json, right_json, op='strict')

判断一个 json 是否包含另外一个 json 的 key,并且 value 相等;

Param:
  • left_json: (dict) 需要判断的 json,我们称之为 left
  • right_json: (dict) 需要判断的 json,我们称之为 right,目前是判断 left 是否包含在 right 中
  • op: (string) 判断操作符,目前只有一种,默认为 strict,向后兼容
Returns:

  • result: (bool) right json 包含 left json 的 key,并且 value 一样,返回 True,否则都返回 False

举例如下:

print('--- json contain demo ---')
json1 = {"id": "0001"}
json2 = {"id": "0001", "value": "File"}
print(if_json_contain(json1, json2))
print('---')

执行结果:

True
fish_common.sorted_list_from_dict(p_dict, order=10011)

根据字典的 value 进行排序,并以列表形式返回

Param:
  • p_dict: (dict) 需要排序的字典
  • order: (int) 排序规则,odASC 升序,odDES 降序,默认为升序
Returns:

  • o_list: (list) 排序后的 list

举例如下:

# 定义待处理字典
dict1 = {'a_key': 'a_value', '1_key': '1_value', 'A_key': 'A_value', 'z_key': 'z_value'}
print(dict1)
# 升序结果
list1 = sorted_list_from_dict(dict1, odASC)
print('ascending order result is:', list1)
# 降序结果
list1 = sorted_list_from_dict(dict1, odDES)
print('descending order result is:', list1)

执行结果:

{'a_key': 'a_value', 'A_key': 'A_value', '1_key': '1_value', 'z_key': 'z_value'}
ascending order result is: ['1_value', 'A_value', 'a_value', 'z_value']
descending order result is: ['z_value', 'a_value', 'A_value', '1_value']
fish_common.splice_url_params(dic)

根据传入的键值对,拼接 url 后面 ? 的参数,比如 ?key1=value1&key2=value2

Param:
  • dic: (dict) 参数键值对
Returns:

  • result: (string) 拼接好的参数

举例如下:

dic1 = {'key1': 'value1', 'key2': 'value2'}
print(splice_url_params(dic1))

执行结果:

?key1=value1&key2=value2

fish_system 系统相关函数包

fish_system 包含的是一些系统相关的函数和类。

fish_system.get_platform()

返回当前程序运行的操作系统名称, 基于 sys.platform() 进行封装;

Param:
Returns:

  • platform: (string) 返回 linux, osx, win 或者其他

举例如下:

print('current os:', get_platform())

执行结果:

current os: osx

fish_file 文件处理函数包

fish_file 包含的是文件、路径处理相关的函数。

各类相对绝对文件的路径处理等都是开发时候经常需要处理的问题,fish_file 中的函数试图简化这些操作。

fish_file.check_sub_path_create(sub_path)

检查当前路径下的某个子路径是否存在, 不存在则创建;

Param:
  • sub_path: (string) 下一级的某路径名称
Returns:

  • 返回类型 (tuple),有两个值
  • True: 路径存在,False: 不需要创建
  • False: 路径不存在,True: 创建成功

举例如下:

# 定义子路径名称
sub_path = 'demo_sub_dir'
# 检查当前路径下的一个子路径是否存在,不存在则创建
print('check sub path:', sub_path)
result = check_sub_path_create(sub_path)
print(result)

输出结果:

check sub path: demo_sub_dir
(True, False)
fish_file.get_abs_filename_with_sub_path(sub_path, filename)

生成当前路径下一级路径某文件的完整文件名;

Param:
  • sub_path: (string) 下一级的某路径名称
  • filename: (string) 下一级路径的某个文件名
Returns:

  • 返回类型 (tuple),有两个值,第一个为 flag,第二个为文件名,说明见下
  • flag: (bool) 如果文件存在,返回 True,文件不存在,返回 False
  • abs_filename: (string) 指定 filename 的包含路径的长文件名

举例如下:

print('get_abs_filename_with_sub_path')
# define sub dir
path_name = 'sub_dir'
# define not exists file
filename = 'test_file.txt'

abs_filename = get_abs_filename_with_sub_path(path_name, filename)
# return False and abs filename
print(abs_filename)

# define exists file
filename = 'demo.txt'
abs_filename = get_abs_filename_with_sub_path(path_name, filename)
# return True and abs filename
print(abs_filename)

输出结果:

(False, '/Users/****/Documents/dev_python/fishbase/demo/sub_dir/test_file.txt')
(True, '/Users/****/Documents/dev_python/fishbase/demo/sub_dir/demo.txt')

fish_csv csv 函数包

fish_csv.csv_file_to_list(csv_filename, deli=', ', del_blank_row=True)

将指定的 csv 文件转换为 list 返回;

Param:
  • csv_filename: (string) csv 文件的长文件名
  • deli: (string) csv 文件分隔符,默认为逗号
  • del_blank_row: (string) 是否要删除空行,默认为删除
Returns:

  • csv_list: (list) 转换后的 list

举例如下:

from fishbase.fish_file import *
from fishbase.fish_csv import *

def test_csv():
    csv_filename = get_abs_filename_with_sub_path('csv', 'test_csv.csv')[1]
    print(csv_filename)
    csv_list = csv_file_to_list(csv_filename)
    print(csv_list)


if __name__ == '__main__':
    test_csv()

fish_logger 日志记录函数包

fish_logger 包含的是日志处理相关的函数。

通过 set_log_file() 可以方便的进行分卷的日志文件记录。

fish_logger.set_log_file(local_file=None)

设置日志记录,按照每天一个文件,记录包括 info 以及以上级别的内容; 日志格式采取日志文件名直接加上日期,比如 fish_test.log.2018-05-27

Param:
  • local_fie: (string) 日志文件名
Returns:

举例如下:

from fishbase.fish_logger import *
from fishbase.fish_file import *

log_abs_filename = get_abs_filename_with_sub_path('log', 'fish_test.log')[1]

set_log_file(log_abs_filename)

logger.info('test fish base log')
logger.warn('test fish base log')
logger.error('test fish base log')

print('log ok')