tools.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. # -*- coding:utf-8 -*-
  2. import math
  3. import logging
  4. import os
  5. import config
  6. import logging.config
  7. import pickle
  8. import mmap
  9. TITLE = "工具类"
  10. tip_internal_cache = {}
  11. def init_log():
  12. """
  13. 日志初始化工具
  14. """
  15. # 读取日志配置文件内容
  16. logging.config.fileConfig('./logging.conf')
  17. # 用一个没有在配置文件中定义的logger名称来创建一个日志器logger
  18. return logging.getLogger()
  19. def log_start_msg(msg):
  20. """
  21. 执行开始时的简易日志输出
  22. """
  23. logging.info("-----------------%s 开始-----------------" % msg)
  24. def log_end_msg(msg):
  25. """
  26. 执行结束时的简易日志输出
  27. """
  28. logging.info("-----------------%s 结束-----------------" % msg)
  29. def get_tip_internal(total_num):
  30. """
  31. 计算进度提示间隔
  32. """
  33. # 尝试从缓存中获取
  34. internal = tip_internal_cache.get(total_num)
  35. # 不存在则进行计算并放入缓存中
  36. if not internal:
  37. internal = math.ceil(total_num * config.PRECENT_TIPS)
  38. tip_internal_cache[total_num] = internal
  39. return internal
  40. def tip(total_num, cur_num, is_zero_base=True):
  41. """
  42. 简易进度提示
  43. total_num 总数量
  44. cur_num 当前进度(0基)
  45. internal 提示间隔
  46. """
  47. # TODO
  48. # 修改成百分比提示
  49. internal = get_tip_internal(total_num)
  50. # cur_num + 1 是0基修正
  51. if is_zero_base:
  52. cur_num = cur_num + 1
  53. # 进度提示
  54. if cur_num == total_num:
  55. logging.info("当前进度 %d / %d" % (total_num, total_num))
  56. elif cur_num % internal == 0:
  57. logging.info("当前进度 %d / %d" % (cur_num, total_num))
  58. def tip_in_size(total_size, cur_pos):
  59. """
  60. 简易进度提示(用于不知道总行数的情形)
  61. total_size 总数量
  62. cur_num 当前进度
  63. """
  64. # 尝试从缓存中获取
  65. tip_internal = tip_internal_cache.get(total_size)
  66. if not tip_internal:
  67. # 不存在缓存,构建 提示检查点 和 提示间隔 信息
  68. internal = math.ceil(total_size * config.PRECENT_TIPS)
  69. tip_internal= {
  70. "check_point": cur_pos,
  71. "internal": internal
  72. }
  73. # 放入缓存
  74. tip_internal_cache[total_size] = tip_internal
  75. # 当前位置超过提示检查点则显示进度
  76. if cur_pos >= tip_internal["check_point"]:
  77. logging.info("当前进度 %d / %d" % (cur_pos, total_size))
  78. # 修改 提示检查点
  79. check_point = tip_internal["check_point"]
  80. internal = tip_internal["internal"]
  81. while cur_pos >= check_point:
  82. check_point = check_point + internal
  83. # 如果 提示检查点大于总值,则置为总值
  84. if check_point > total_size:
  85. check_point = total_size
  86. # 如果不手动中断会陷入循环
  87. break
  88. # 更新 提示检查点
  89. tip_internal["check_point"] = check_point
  90. def save_obj(path, obj):
  91. """
  92. 保存对象至本地
  93. """
  94. with open(path, "wb") as f:
  95. pickle.dump(obj, f)
  96. def load_obj(path):
  97. """
  98. 加载对象
  99. """
  100. with open(path, "rb") as f:
  101. return pickle.load(f)
  102. if __name__ == "__main__":
  103. init_log()
  104. log_start_msg(TITLE)
  105. # 测试普通提示
  106. # total = 3
  107. # for i in range(total):
  108. # tip(total, i)
  109. # 测试mmap的提示
  110. # with open(config.KEY_FILE, "r", encoding=config.ENCODING_CHARSET) as fkey, \
  111. # mmap.mmap(fkey.fileno(), 0, access=mmap.ACCESS_READ) as fmmap:
  112. # # 总大小
  113. # total_num = fmmap.size()
  114. # while True:
  115. # # 读取光标位置
  116. # cur_pos = fmmap.tell()
  117. # # 把光标移动到下一行
  118. # line = fmmap.readline()
  119. # # 进度显示
  120. # tip_in_size(total_num, cur_pos)
  121. # if not line:
  122. # break
  123. # 测试逐行读取的进度提示
  124. with open(config.KEY_FILE, "r", encoding=config.ENCODING_CHARSET) as fkey:
  125. fkey.seek(0, os.SEEK_END)
  126. total_num = fkey.tell()
  127. fkey.seek(0)
  128. while True:
  129. cur_pos = fkey.tell()
  130. line = fkey.readline()
  131. tip_in_size(total_num, cur_pos)
  132. if not line:
  133. break;
  134. log_end_msg(TITLE)