自定义模块

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. # 为什么要有模块?(内置函数不够用)
  4. # 和操作系统打交道
  5. # 和python解释器打交道
  6. # 和时间打交道
  7. # 如何利用python发邮件
  8. # 如何利用python图像识别
  9. # 都是完成好的功能
  10. # 可以被封装成函数
  11. # 可以成为内置的函数
  12. # 占用内存空间
  13. # 整理分类,把相同的功能放在一个文件中
  14. # 我们在开发的过程中,用到哪个功能直接导入使用就可以了
  15. # 不使用的功能不会进入内存占用不必要的空间
  16. # 使用的功能我们可以自由的选择
  17. # 模块的本质
  18. # 就是封装了很多很多函数、功能的一个文件
  19. # 导入模块 就是 import
  20. # 模块的分类
  21. # 内置模块 不需要我们进行额外的安装、随着解释器的安装直接就可以使用的模块
  22. # 扩展模块/第三方模块 我们安装了python解释器之后 如果要使用这些模块还要单独安装
  23. # https://pypi.org/
  24. # 豆瓣的 python源
  25. # 自定义模块
  26. # 自己写的模块
  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. # 引用模块相当于执行这个模块
  4. # 重复引用会直接引用内存中已经加载好的模块结果
  5. # import tom
  6. # import tom
  7. # 模块被引用发生了三件事:
  8. # 1,创建一个以被导入模块的名字命名的名称空间
  9. # 2,自动执行模块中的代码(将模块中的所有内容加载到内存)
  10. # 3,要想执行模块中的代码必须通过模块名.的方式执行获取
  11. from tom import change
  12. import tom
  13. print(tom.name) # 汤姆
  14. tom.read1() # tom模块: 汤姆
  15. name = '杰瑞'
  16. print(tom.name) # 汤姆
  17. print(name) # 杰瑞
  18. print("------------------ 1 ---------------------")
  19. # 模块的改名
  20. # 1,模块名过长,引用不方便,给模块改名,简化引用。
  21. import abcdpythonuser as ab
  22. print(ab.age) # 18
  23. ab.func() # 666
  24. print("------------------ 2 ---------------------")
  25. # 2, 优化代码。
  26. # import mysql
  27. # import oracle
  28. # db_sql = input('>>> ')
  29. # if db_sql == 'mysql':
  30. # mysql.sql_parse()
  31. # elif db_sql == 'orcle':
  32. # orcle.sql_parse()
  33. # 改版
  34. # db_sql = input('>>> ')
  35. # if db_sql == 'mysql':
  36. # import mysql as db
  37. # elif db_sql == 'oracle':
  38. # import orcle as db
  39. # db.sql_parse()
  40. # print("------------------ 3 ---------------------")
  41. # 引用多个模块
  42. # 标准的:
  43. # import mysql
  44. # import time
  45. # import sys
  46. # 不建议:
  47. # import mysql,time,os,sys
  48. # from ..... import .....
  49. # 执行过程:
  50. # 1,执行一遍tom的所有代码,加载到内存。
  51. # 2,将name,read1这些实际引用过来的变量函数在本文件复制一份。
  52. # globals()查看
  53. # 好处:使用简单
  54. # 坏处:容易与本文件的变量,函数名等发生冲突
  55. from tom import change,name,read1
  56. name = '小虎'
  57. def read1():
  58. print(666)
  59. print(name) # 小虎
  60. read1() #666
  61. from tom import change,name,read1
  62. print(name) # 汤姆
  63. read1() # tom模块: 汤姆
  64. # print(globals())
  65. print("------------------ 4 ---------------------")
  66. # 起别名:
  67. from tom import read1 as r
  68. r()
  69. print("------------------ 5 ---------------------")
  70. #导入多个:
  71. # 方式一
  72. # from tom import name
  73. # from tom import raed1
  74. # 方式2
  75. # from tom import name,read1,read2
  76. print("------------------ 6 ---------------------")
  77. # 导入所有:一般不用
  78. # from tom import *
  79. # print(globals())
  80. # 如果使用只有两点:
  81. # 1,将导入的模块中的所有的代码全部清楚的前提下,可以使用 *
  82. # from time import time
  83. # 2,只是用一部分
  84. # from tom import *
  85. # read1()
  86. # read2()
  87. # read3()
  88. # change()
  89. # import tom
  90. # 文件有个两个作用:
  91. # 1,作为脚本,直接运行
  92. # 2,作为模块供别人使用。
  93. # 3, __name__ == '__main__' 可以作为一个项目的启动文件用。
  94. # 模块的搜索路径
  95. # 先从内存中寻找 -----> built-in 内置模块 -----> sys.path找
  96. import sys
  97. print(sys.path) # 返回一个列表 ,列表的第一个参数就当前目录。
  98. print("------------------ 7 ---------------------")

tom.py

  1. # -*- coding: utf-8 -*-
  2. # __all__ = ['read1','read2'] # 控制 * 的范围。 from tom import * 只会导入 read1 read2
  3. print('from the tom.py')
  4. name = '汤姆'
  5. def read1():
  6. print('tom模块:', name)
  7. def read2():
  8. print('tom模块')
  9. read1()
  10. def read3():
  11. print('read3....')
  12. def read4():
  13. # dic = dict([('a', 1), ('b', 2), ('c', 3)])
  14. # print(dic)
  15. l1 = [1,2,3]
  16. l2 = ['a','b','c']
  17. print(dict(zip(l1,l2)))
  18. def change():
  19. global name
  20. name = 'tom'
  21. # print(666)
  22. # return name
  23. # read4()
  24. # print(__name__) # 在本文件运行,__name__ == __mian__
  25. if __name__ == '__main__':
  26. read3()

abcdpythonuser.py

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. age = 18
  4. def func():
  5. print(666)

mysql.py

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. def sql_parse():
  4. print('from mysql sql parse')

oracle.py

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. def sql_parse():
  4. print('from mysql sql parse')

常用内置模块

time模块

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. # time模块 和时间打交道的模块
  4. import time
  5. # 1.时间戳时间 time.time()
  6. print(time.time()) # 1618384314.988371 时间戳格式
  7. # float 小数
  8. # 为什么时间要用这种格式(1618384314.988371)表示?
  9. # 是给计算机看的
  10. # '2019/1/27 11:13'
  11. # 1970 1 1 0:0:0 英国伦敦的时间 0时区
  12. # 1970 1 1 8:0:0 北京的时间 东8区
  13. print("--------------- 1 ---------------------------")
  14. # 2.格式化时间 time.strftime('%Y-%m-%d %H:%M:%S')
  15. t1 = time.strftime('%Y-%m-%d %H:%M:%S')
  16. print(t1)
  17. t1 = time.strftime('%Y+%m+%d %H:%M:%S %a')
  18. print(t1)
  19. t1 = time.strftime('%Y+%m+%d %H:%M:%S %A %b %B')
  20. print(t1)
  21. t1 = time.strftime('%c')
  22. print(t1)
  23. print("--------------- 2 ---------------------------")
  24. # 3.结构化时间(时间元组) time.localtime()
  25. # time.struct_time(tm_year=2021, tm_mon=4, tm_mday=14, tm_hour=15, tm_min=18, tm_sec=52, tm_wday=2, tm_yday=104, tm_isdst=0)
  26. # print(time.localtime())
  27. # tm_year=2019 --- 年
  28. # tm_mon=1 ---月
  29. # tm_mday=28, ---日
  30. # tm_hour=11, ---时
  31. # tm_min=33, ---分
  32. # tm_sec=1, ---秒
  33. # tm_wday=0, --- 一周的第几天,星期一为0
  34. # tm_yday=28, --- 一年的第几天
  35. # tm_isdst=0 --- 是否是夏令时,默认不是
  36. # 转换只能通过结构化时间进行转换
  37. # 时间戳格式 <---> 结构化时间 <---> 格式化时间
  38. # 1548558746.5218766 '2019/1/27 11:13'
  39. # 计算机能看懂的 (为了进行数据转换) 人能看懂的
  40. # 时间戳时间 结构化时间 格式化时间
  41. # time.time() time.localtime() time.strftime('%Y-%m-%d %H:%M:%S')
  42. # 举例1
  43. # 格式化时间 2018-8-8 ---> 时间戳时间
  44. # 1.1,先把格式化时间 转化成 元组时间
  45. str_time = '2018-8-8'
  46. struct_time = time.strptime(str_time, '%Y-%m-%d')
  47. print(struct_time)
  48. # 1.2,在转化成时间戳
  49. stamp_time = time.mktime(struct_time)
  50. print(stamp_time)
  51. print("--------------- 3.1 ---------------------------")
  52. # 举例2
  53. # 2000000000 转化为格式化时间
  54. # 2.1,先把时间戳时间转化为元组时间
  55. stamp_t = 2000000000
  56. struct_t = time.localtime(stamp_t)
  57. print(struct_t)
  58. # 2.2,再把元组时间转为格式化时间
  59. strftime_t = time.strftime('%Y-%m-%d %H:%M:%S', struct_t)
  60. print(strftime_t)
  61. print("--------------- 3.2 ---------------------------")
  62. # 小练习1
  63. # 拿到本月时间1号的时间戳时间
  64. # 1,拿到本月的格式化时间
  65. strftime_t = time.strftime('%Y-%m')
  66. print(strftime_t)
  67. # 2,转化为结构化元组时间
  68. struct_t = time.strptime(strftime_t, '%Y-%m')
  69. print(struct_t)
  70. # 3,转化为时间戳时间
  71. stamp_t = time.mktime(struct_t)
  72. print(stamp_t)
  73. print("--------------- 4 ---------------------------")
  74. # 小练习2
  75. # '2017-09-11 08:30:00' '2018-09-13 08:30:10' 计算这两个时间段的时间差
  76. # 先把格式化时间--->元组时间--->时间戳时间
  77. t1 = time.mktime(time.strptime('2017-09-11 08:30:00', '%Y-%m-%d %H:%M:%S'))
  78. t2 = time.mktime(time.strptime('2018-09-13 08:30:10', '%Y-%m-%d %H:%M:%S'))
  79. print(t1)
  80. print(t2)
  81. ret = t2 - t1
  82. struct_t = time.gmtime(ret)
  83. print(struct_t)
  84. print('相差%d年%d月%d天%d小时%d分钟%d秒' % (
  85. struct_t.tm_year - 1970,
  86. struct_t.tm_mon - 1,
  87. struct_t.tm_mday - 1,
  88. struct_t.tm_hour - 0,
  89. struct_t.tm_min - 0,
  90. struct_t.tm_sec - 0,
  91. ))

datetime模块

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. import datetime
  4. now_time = datetime.datetime.now()
  5. print(now_time) # 2021-04-14 15:29:52.021695
  6. print(now_time + datetime.timedelta(weeks=3))
  7. print(now_time + datetime.timedelta(weeks=-3))
  8. print(now_time + datetime.timedelta(days=-3))
  9. print(now_time + datetime.timedelta(days=3))
  10. print(now_time + datetime.timedelta(hours=3))
  11. print("-------- 1 -----------")
  12. # 直接调整
  13. print(now_time.replace(year=2010))
  14. print(now_time.replace(month=10))
  15. print(now_time.replace(year=1989, month=4, day=25))
  16. print(now_time.replace(year=1989, month=4, day=25, hour=14, minute=10, second=10))
  17. print("-------- 2 -----------")
  18. print(datetime.date.fromtimestamp(time.time()))

logging模块

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. # logging
  4. # 什么时候需要打印日志?
  5. # 任何操作?
  6. # 个性化推荐,淘宝,京东,知乎,网易云音乐等等
  7. # 只要给你做记录,都可以当做广义的日志
  8. # 开发中的日志:
  9. # 1,日志帮助你调试代码
  10. # 2,代码的警告,危险提示作用
  11. # 3,你对服务器的操作命令
  12. # 4,重要的节点,需要日志提示
  13. # 低配
  14. # 低配版:不能同时屏幕输出和文件写入
  15. # import logging
  16. # import time
  17. # logging.debug('debug message') # 调试模式
  18. # logging.info('info message') # 正常运转模式
  19. # logging.warning('warning message 1') # 警告模式
  20. # logging.error('error message 2') # 错误模式
  21. # logging.critical('critical message 3') # 致命的 崩溃模式
  22. #
  23. # while 1:
  24. # try:
  25. # num = input('>>>:')
  26. # int(num)
  27. # except ValueError:
  28. # logging.warning('输入非数字元素,警告!')
  29. # time.sleep(1)
  30. # break
  31. # print("-------------- 1 --------------------")
  32. # 制定显示信息格式
  33. # import logging
  34. # logging.basicConfig(
  35. # # level=logging.DEBUG,
  36. # level=20, # 设置级别
  37. # format='%(asctime)s %(filename)s [line:%(lineno)d] %(levelname)s %(message)s',
  38. # # datefmt='%a, %d %b %Y %H:%M:%S', # 显示时间格式
  39. # # filename='test.log',
  40. # # filemode='w'
  41. # )
  42. # logging.debug('debug message 1') # 调试模式 10
  43. # logging.info('info message 2') # 正常运转模式 20
  44. # logging.warning('warning message 3') # 警告模式 30
  45. # logging.error('error message 4') # 错误模式 40
  46. # logging.critical('critical message 5') #致命的 崩溃模式 50
  47. # print("-------------- 2 --------------------")
  48. # # 标配
  49. # # 1.产生logger对象
  50. # import logging
  51. # logger = logging.getLogger()
  52. #
  53. # # 2 产生其他对象(屏幕对象,文件对象)
  54. # sh = logging.StreamHandler() # 屏幕对象
  55. # fh1 = logging.FileHandler('staff.log', encoding='utf-8') # 文件对象
  56. # fh2 = logging.FileHandler('boss.log', encoding='utf-8') # 文件对象
  57. #
  58. # # 3,设置显示格式
  59. # formater = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # 执行设置显示格式
  60. # formater1 = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # 执行设置显示格式
  61. # formater2 = logging.Formatter('%(asctime)s-%(message)s') # 执行设置显示格式
  62. #
  63. # # 4,给对象绑定格式
  64. # sh.setFormatter(formater)
  65. # fh1.setFormatter(formater1)
  66. # fh2.setFormatter(formater2)
  67. #
  68. # # 5 给logger对象绑定其他对象
  69. # logger.addHandler(sh)
  70. # logger.addHandler(fh1)
  71. # logger.addHandler(fh2)
  72. #
  73. # # 6 设置显示级别
  74. # # 其他对象的级别要高于logger的级别
  75. # logger.setLevel(40)
  76. # sh.setLevel(20)
  77. # fh1.setLevel(30)
  78. # fh2.setLevel(50)
  79. #
  80. #
  81. # logging.debug('debug message 1') # 调试模式 10
  82. # logging.info('info message 2') # 正常运转模式 20
  83. # logging.warning('warning message 3') # 警告模式 30
  84. # logging.error('error message 4') # 错误模式 40
  85. # logging.critical('critical message 5') #致命的 崩溃模式 50
  86. # print("-------------- 3 --------------------")
  87. # 高配 真正的工作中,是自定制个性化日志
  88. import os
  89. import logging.config
  90. # 定义三种日志输出格式 开始
  91. # 标准版 格式
  92. standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
  93. '[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字
  94. # 简单版 格式
  95. simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
  96. # boss版格式
  97. id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'
  98. # 定义日志输出格式 结束
  99. logfile_name = r'staff.log' # log文件名
  100. # log配置字典
  101. LOGGING_DIC = {
  102. 'version': 1, # 版本
  103. 'disable_existing_loggers': False, # 可否重复使用之前的logger对象
  104. 'formatters': {
  105. 'standard': {
  106. 'format': standard_format
  107. },
  108. 'simple': {
  109. 'format': simple_format
  110. },
  111. 'boss_formatter':{
  112. 'format': id_simple_format
  113. },
  114. },
  115. 'filters': {},
  116. 'handlers': {
  117. # 打印到终端的日志
  118. 'stream': {
  119. 'level': 'DEBUG',
  120. 'class': 'logging.StreamHandler', # 打印到屏幕
  121. 'formatter': 'simple'
  122. },
  123. # 打印到文件的日志,收集info及以上的日志 文件句柄
  124. 'file': {
  125. 'level': 'INFO',
  126. 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件
  127. 'formatter': 'standard', #标准
  128. 'filename': logfile_name, # 日志文件
  129. 'maxBytes': 30000, # 日志大小 30000 bit
  130. 'backupCount': 5, # 轮转文件数
  131. 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
  132. },
  133. },
  134. 'loggers': {
  135. # logging.getLogger(__name__)拿到的logger配置
  136. '': {
  137. 'handlers': ['stream', 'file'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
  138. 'level': 'DEBUG', # 总级别
  139. 'propagate': True, # 向上(更高level的logger)传递
  140. },
  141. },
  142. }
  143. # 字典中第一层的所有key都是固定不可变的
  144. # import logging
  145. # logging.config.dictConfig(LOGGING_DIC)
  146. # logger = logging.getLogger() # 这个logger对象是通过自己个性化配置的logger对象
  147. # logger.debug('调试模式1')
  148. # logger.info('运转正常2')
  149. # logger.warning("警告 3")
  150. # logger.error("错误 4")
  151. # logger.critical("严重错误 5")
  152. def load_my_logging_cfg():
  153. logging.config.dictConfig(LOGGING_DIC) # 导入上面定义的logging配置
  154. logger = logging.getLogger(__name__) # 生成一个log实例
  155. logger.info('It works!') # 记录该文件的运行状态
  156. if __name__ == '__main__':
  157. load_my_logging_cfg()

模拟其他模块调用日志模块

logging_test.py

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. import logging
  4. import logging.config
  5. # 1 定义日志格式,分为标准版,简单版,low版,可以自定义
  6. # 标准版
  7. standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
  8. '[%(levelname)s][%(message)s]' # 其中name为getlogger指定的名字
  9. # 简单版
  10. simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
  11. # low版
  12. id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'
  13. # 2 定义日志输出文件,也可以只定义一个文件
  14. logfile_name = r'stafftest.log'
  15. logfile_boss = r'bosstest.log'
  16. # 3 logging模块配置字典
  17. # 字典中第一层的所有key都是固定不可变的
  18. LOGGING_DIC = {
  19. 'version': 1, # 版本
  20. 'disable_existing_loggers': False, # 可否重复使用之前的logger对象
  21. 'formatters': { # 日志格式,第一步定义的
  22. 'standard': {
  23. 'format': standard_format
  24. },
  25. 'simple': {
  26. 'format': simple_format
  27. },
  28. 'boss_formatter': {
  29. 'format': id_simple_format
  30. },
  31. },
  32. 'filters': {}, # 过滤
  33. 'handlers': {
  34. # 打印到终端的日志
  35. 'stream': {
  36. 'level': 'DEBUG',
  37. 'class': 'logging.StreamHandler', # 打印到屏幕
  38. 'formatter': 'simple'
  39. },
  40. # 打印到文件的日志,收集info及以上的日志 文件句柄
  41. 'file': {
  42. 'level': 20,
  43. 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件
  44. 'formatter': 'standard', # 标准
  45. 'filename': logfile_name, # 日志文件
  46. 'maxBytes': 3000000, # 日志大小 3000000 bit
  47. 'backupCount': 5, # 轮转文件数
  48. 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
  49. },
  50. 'boss': {
  51. 'level': 20,
  52. 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件
  53. 'formatter': 'boss_formatter', # low版
  54. 'filename': logfile_boss, # 日志文件
  55. 'maxBytes': 300, # 日志大小 300 bit
  56. 'backupCount': 5, # 轮转文件数
  57. 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
  58. },
  59. },
  60. 'loggers': {
  61. # logging.getLogger(__name__)拿到的logger配置
  62. '': {
  63. 'handlers': ['stream', 'file', 'boss'], # 这里把上面定义的handler都加上,即log数据既写入文件又打印到屏幕
  64. 'level': 'DEBUG', # 总级别
  65. 'propagate': True, # 向上(更高level的logger)传递
  66. },
  67. },
  68. }
  69. # 4 定义一个函数,供其他模块调用
  70. def get_logger(taskid):
  71. logging.config.dictConfig(LOGGING_DIC)
  72. logger = logging.getLogger(taskid) # 这个logger对象是通过自己个性化配置的logger对象
  73. return logger # 返回logger对象供使用者调用
  74. if __name__ == '__main__':
  75. logger1 = get_logger('测试业务') # 调用函数,获取返回值logger对象
  76. logger1.info('打印日志logger1')
  77. # 其他业务模块调用
  78. logger2 = get_logger('其他业务')
  79. logger2.error('错误日志')

test.py

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. from logging_test import get_logger
  4. logger1 = get_logger('模拟其他模块调用日志模块')
  5. logger1.info('日志打印')

random模块

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. # 和随机相关的内容 random模块
  4. import random
  5. # 随机小数
  6. print(random.random()) # (0,1)
  7. print(random.uniform(1, 2)) # (n,m)
  8. print("------ 1 ---------------------------------------------")
  9. # 随机整数
  10. print(random.randint(1, 2)) # [1, 2] 包含了2
  11. print(random.randrange(1, 2)) # [1, 2) 不包含2
  12. print(random.randrange(1, 5, 2)) # 步长为2
  13. print("------ 2 ---------------------------------------------")
  14. # 随机从一个列表中取一个值
  15. ret = random.choice([1, 2, 3, ('k', 'v'), {'name': 'tom'}])
  16. print(ret)
  17. print("------ 3 ---------------------------------------------")
  18. # 随机从一个列表中取2个值
  19. ret2 = random.sample([1, 2, 3, ('k', 'v'), {'name': 'tom'}], 2)
  20. print(ret2)
  21. print("------ 4 ---------------------------------------------")
  22. # 打乱顺序 洗牌
  23. l1 = [1, 2, 3, 4, 5]
  24. random.shuffle(l1)
  25. print(l1)
  26. print("------ 5 ---------------------------------------------")
  27. # 验证码例子
  28. def my_code(n=6, flag=True):
  29. code = ''
  30. for i in range(n):
  31. num = random.randint(0, 9)
  32. # 注意这里的小技巧
  33. # 字母和数字混合
  34. if flag:
  35. alp = chr(random.randint(65, 90)) # A-Z 字母随机
  36. num = random.choice([num, alp]) # 字母和数字之中取一个
  37. code += str(num)
  38. return code
  39. # ret = my_code(n=4, flag=False)
  40. ret = my_code()
  41. print(ret)
  42. print("------ 6 ---------------------------------------------")
  43. # 红包例子
  44. # 思路:
  45. # 1.需要确定红包个数,红包总金额
  46. # 2.最低金额为0.01元
  47. # 3.每抽中一次,需要用红包当前总金额减去抽中的金额,然后在继续在该区间内随机抽取
  48. def hb(num, money):
  49. # 定义空列表用来存储抽奖金额
  50. lst = []
  51. # 金额乘以100,便于计算,后续加入到列表在除以100
  52. money = int(money * 100)
  53. # 判断传递参数的合法性
  54. if type(num) is int and num >=1 and (type(money) is int or type(money) is float):
  55. # for循环应该比num少一次,例如2个红包个数,for循环1次就可以
  56. for i in range(1, num):
  57. # 保证不出现抽中0元的现象
  58. p = random.randint(1, money - (num - i))
  59. lst.append(p / 100)
  60. # 需要减去已经抽取的红包金额
  61. money = money - p
  62. else:
  63. # 循环结束了,把剩余的红包总金额放入到一个红包内
  64. lst.append(money / 100)
  65. return lst
  66. else:
  67. print('参数有误!')
  68. ret = hb(3, 0.04)
  69. print(ret)

os模块

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. import os
  4. # os和操作系统打交道的
  5. # 和文件、文件夹相关的
  6. # os.makedirs('dirname1/dirname2') # 可生成多层递归目录
  7. # os.removedirs('dirname1/dirname2') # 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
  8. # os.mkdir('dirname') # 生成单级目录;相当于shell中mkdir dirname
  9. # os.rmdir('dirname') # 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
  10. # ret = os.listdir(r'/tmp') # 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
  11. # print(ret)
  12. # os.remove('test.py') # 删除一个文件
  13. # os.rename("test.py", "test2.py") # 重命名文件/目录
  14. # ret = os.stat(r'test.py') # 获取文件/目录信息
  15. # print(ret)
  16. # print("------------- 1 ----------------")
  17. # 和执行系统命令相关
  18. # os.system("dir") # 运行shell命令,直接显示
  19. # ret = os.popen('dir').read() # 运行shell命令,获取执行结果
  20. # print(ret)
  21. # ret = os.getcwd() # 获取当前工作目录,即当前python脚本工作的目录路径
  22. # print(ret)
  23. # os.chdir(r"/tmp") # 改变当前脚本工作目录;相当于shell下cd
  24. # ret = os.getcwd()
  25. # print(ret)
  26. # # 所谓工作目录 文件在哪个目录下运行 工作目录就是哪里
  27. # # 和这个文件本身所在的路径没有关系
  28. # # 1.工作目录与文件所在位置无关
  29. # # 2.工作目录和所有程序中用到的相对目录都相关
  30. # print("------------- 2 ----------------")
  31. # 和路径相关的
  32. # os.path
  33. # ret = os.path.abspath(__file__) # 返回path规范化的绝对路径
  34. # print(ret)
  35. # ret = os.path.split(__file__) # 将path分割成目录和文件名二元组返回
  36. # print(ret)
  37. # os.path.dirname(path) # 返回path的目录。其实就是os.path.split(path)的第一个元素
  38. # os.path.basename(path) # 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
  39. # ret = os.path.exists(r'E:\python') # 如果path存在,返回True;如果path不存在,返回False
  40. # print(ret)
  41. # ret = os.path.isabs('E:\python3周末班2期笔记\05 day05\03 笔记整理') # 如果path是绝对路径,返回True
  42. # print(ret)
  43. # ret = os.path.isfile('E:\python3周末班2期笔记\05 day05\03 笔记整理') # 如果path是一个存在的文件,返回True。否则返回False
  44. # print(ret)
  45. # ret = os.path.isdir('E:\python3周末班2期笔记') # 如果path是一个存在的目录,则返回True。否则返回False
  46. # print(ret)
  47. # ret = os.path.join('E:\python3周末班2期笔记', 'abc', 'def') # 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
  48. # print(ret)
  49. # os.path.getatime(path) 返回path所指向的文件或者目录的最后访问时间
  50. # os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间
  51. # ret = os.path.getsize(r'E:\python3周末班2期笔记\05 day05\03 笔记整理\00 今日课程大纲.py')
  52. # 返回path的大小,文件夹的大小不准确
  53. # print(ret)
  54. # print("------------- 3 ----------------")
  55. # 练习题
  56. # 使用python代码 计算文件夹的大小
  57. # 文件夹里可能还有文件夹
  58. # import os
  59. # total_size=0
  60. # def file_size(path):
  61. # global total_size
  62. # path=os.path.abspath(path)
  63. # print('path',path)
  64. # file_list=os.listdir(path)
  65. # print('list',file_list)
  66. # for i in file_list:
  67. # i_path = os.path.join(path, i)
  68. # if os.path.isfile(i_path):
  69. # total_size += os.path.getsize(i_path)
  70. # else:
  71. # try:
  72. # file_size(i_path)
  73. # except RecursionError:
  74. # print('递归操作时超出最大界限')
  75. # return total_size
  76. #
  77. # print(file_size(r'E:\02'))
  78. # print("------------- 4 ----------------")

sys模块

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. import sys
  4. # sys模块是和 python解释器打交道的
  5. # sys.exit() # 退出
  6. # print(123)
  7. # print(sys.version) # 版本
  8. # print(sys.platform) # 平台 操作系统
  9. # print(sys.path) # 模块搜索路径
  10. # 包含的内容
  11. # 1.内置的python安装的时候就规定好的一些内置模块所在的路径
  12. # 内置模块
  13. # 扩展模块
  14. # 2.当前被执行的文件所在的路径
  15. # 自定义的模块
  16. # 需要在CMD执行
  17. # python py文件的目录 参数1 参数2
  18. # print(sys.argv) # []
  19. # if sys.argv[1] == 'tom' and sys.argv[2] == '123':
  20. # print('登陆成功')
  21. # else:
  22. # print('登陆失败')
  23. # sys.exit()
  24. # print('登陆成功后的所有代码')

json模块

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. # 序列化模块
  4. # 序列化
  5. # 序列 list str tuple bytes
  6. # 可迭代的都是序列?字典?集合?无序的,散列。不是序列
  7. # 狭义的序列 str / bytes
  8. # 序列化?把...变得有序,把...变成str或者是bytes
  9. # 反序列化?把str/bytes 还原回原来的 ...
  10. # 为什么要有序列化?
  11. # 1.存储在文件中 长久保存到硬盘
  12. # 2.在网络上传递,只能用字节
  13. # 序列化模块
  14. import json
  15. # 能够支持所有的计算机高级语言
  16. # 对数据类型的要求非常严格
  17. dic = {"key": "value"}
  18. ret = json.dumps(dic) # 序列化方法
  19. print(dic, type(dic)) # {'key': 'value'} <class 'dict'>
  20. print(ret, type(ret)) # {"key": "value"} <class 'str'>
  21. with open('json_file', 'w') as f:
  22. f.write(ret)
  23. with open('json_file') as f:
  24. content = f.read()
  25. d = json.loads(content) # 反序列化方法
  26. print(d, type(d)) # {'key': 'value'} <class 'dict'>
  27. print(d['key'])
  28. print("------------ 1 ------------------------------")
  29. # 1:json格式规定所有的key必须是字符串数据类型
  30. dic = {1: 2}
  31. ret = json.dumps(dic)
  32. print(dic[1]) # 2
  33. print(ret) # {"1": 2}
  34. new_dic = json.loads(ret)
  35. print(new_dic) # {'1': 2}
  36. print("------------ 2 ------------------------------")
  37. # 2 : json中的所有tuple都会被当作list处理
  38. dic = {1: (1, 2, 3)}
  39. ret = json.dumps(dic)
  40. print(ret) # {"1": [1, 2, 3]}
  41. new_dic = json.loads(ret)
  42. print(new_dic) # {"1": [1, 2, 3]}
  43. print("------------ 3 ------------------------------")
  44. # 3: json能支持的数据类型非常有限,字符串 数字 列表 字典
  45. # dumps loads 字符串 和 其他基础数据类型之间转换
  46. # dump load 文件 和 其他基础数据类型之间转换
  47. # dump load
  48. dic = {"key": "value"}
  49. with open('json_file2', 'w') as f:
  50. json.dump(dic, f)
  51. with open('json_file2') as f:
  52. ret = json.load(f)
  53. print(ret['key']) # value
  54. print("------------ 4 ------------------------------")
  55. # json不可以dump多次
  56. dic = {"key": "value"}
  57. with open('json_file3', 'w') as f:
  58. json.dump(dic, f)
  59. # json.dump(dic, f) # dump多次会报错
  60. with open('json_file3', 'r') as f:
  61. ret = json.load(f)
  62. print(ret)
  63. print("------------ 5 ------------------------------")
  64. # 如果需要dump多次,按照下面的方法
  65. str_dic = {"name": "tom", "sex": None}
  66. ret = json.dumps(str_dic)
  67. with open('json_file4', 'w') as f:
  68. f.write(ret+'\n')
  69. f.write(ret+'\n')
  70. with open('json_file4', 'r') as f:
  71. for line in f:
  72. print(json.loads(line), type(json.loads(line)))

pickle模块

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. import pickle
  4. # 1.支持几乎所有python中的数据类型
  5. # 2.只在python语言中通用
  6. # 3.pickle适合与bytes类型打交道的
  7. s = {1, 2, 3, 4}
  8. print(type(s)) # <class 'set'>
  9. ret = pickle.dumps(s)
  10. print(ret)
  11. ret2 = pickle.loads(ret)
  12. print(ret2)
  13. print("--------------- 1 -----------------")
  14. # pickle:序列化时候数据是什么类型,反序列化以后数据还是原来的类型,这点和 json 有点不一样
  15. d = {1: 2, 3: 4}
  16. ret = pickle.dumps(d)
  17. print(ret)
  18. new_d = pickle.loads(ret)
  19. print(new_d)
  20. print("--------------- 2 -----------------")
  21. # 写入文件
  22. s = {(1, 2, 3): 2, 3: 4}
  23. result = pickle.dumps(s)
  24. print(result)
  25. with open('pickle_file', 'wb') as f:
  26. f.write(result)
  27. with open('pickle_file', 'rb') as f:
  28. content = f.read()
  29. ret = pickle.loads(content)
  30. print(ret, type(ret))
  31. print("--------------- 3 -----------------")
  32. # pickle 可以支持多个对象放入文件
  33. # pickle 可以dump多次,也可以load多次
  34. s1 = {1, 2, 3}
  35. s2 = {1: 2, 3: 4}
  36. s3 = ['k', 'v', (1, 2, 3), 4]
  37. with open('pickle_file2', 'wb') as f:
  38. pickle.dump(s1, f)
  39. pickle.dump(s2, f)
  40. pickle.dump(s3, f)
  41. with open('pickle_file2', 'rb') as f:
  42. count = 1
  43. while count <= 3:
  44. try:
  45. content = pickle.load(f)
  46. print(content)
  47. count += 1
  48. except EOFError:
  49. break
  50. print("--------------- 4 -----------------")
  51. # json 实际上使用json更多 优先选择
  52. # 如果你是要跨平台沟通,那么推荐使用json
  53. # key只能是字符串
  54. # 不能多次load和dump
  55. # 支持的数据类型有限
  56. # pickle
  57. # 如果你是只在python程序之间传递消息,并且要传递的消息是比较特殊的数据类型
  58. # 处理文件的时候 rb/wb
  59. # 支持多次dump/load

re模块

正则表达式

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. # 正则表达式
  4. # re模块 是用来在python中操作 正则表达式 的
  5. # 要先知道正则表达式是什么?做什么用的?怎么用
  6. # 正则表达式检测网站
  7. # http://tool.chinaz.com/regex/
  8. # 邮箱地址
  9. # 用户名 密码
  10. # 要检测一个用户输入的内容是否符合我的规则
  11. # 用户输入的内容对于程序员来说都是字符串
  12. # 一个文件是一堆字符串,有很多内容
  13. # 检测某一个字符串是否符合规则 需求一
  14. # 从一大段文字中找到符合规则的字符串 需求二
  15. # 正则表达式 --> 字符串规则匹配的
  16. # 1.判断某一个字符串是否符合规则
  17. # 2.从一段文字中提取出符合规则的内容
  18. # 初识正则表达式
  19. # 字符组的概念
  20. # [ ]表示字符组,一个[ ]表示一个字符组
  21. # [1-9]
  22. # [0-9]
  23. # [1-5]
  24. # [a-z]
  25. # [a-f]
  26. # 1.对字母来说 区分大小写
  27. # 2.a-f可以 f-a不行
  28. # 一个字符位置上可以出现的内容是匹配数字或字母:[0-9a-zA-Z]
  29. # 匹配一个两位数:# [1-9][0-9]
  30. # 元字符
  31. # \d 数字
  32. # \w 数字 字母 下划线
  33. # \s 空格 回车 制表符
  34. # \t 制表符
  35. # \n 回车
  36. # \b 匹配一个单词的边界。例如 hello world o\b会匹配hello的o
  37. # \D 非数字
  38. # \W 非数字字母下划线
  39. # \S 非空白
  40. # ^ 一个字符串的开始
  41. # $ 一个字符串的结尾
  42. # ^xxxx$ 约束的了整个字符串中的内容必须一一与表达式对应上
  43. # 例如: hello hello hello
  44. # ^hello 只能匹配第一个hello
  45. # hello$ 只能匹配最后一个hello
  46. # hello^ 不能匹配任何字符串。因为 ^ 是开头,没有可能在开头在出现字符。
  47. # | 表示或
  48. # 例子:匹配ab或abc 要这样写 abc|ab 把长的表达式写在前面
  49. # () 分组
  50. # a(b|c)d
  51. # 例子:www.baidu.com www.baide.com 表达式 www.baid(u|e).com
  52. # . 表示除了换行符以外的任意字符
  53. # 非 字符组
  54. # [^ABC] 只要不是ABC都能匹配
  55. # 量词
  56. # {n} 在这个量词前面的一个元字符出现n次
  57. # {n,} 在这个量词前面的一个元字符出现n次或n次以上
  58. # {n,m} 在这个量词前面的一个元字符出现n次到m次以上
  59. #
  60. # ? 在这个量词前面的一个元字符出现0次或者1次
  61. # + 在这个量词前面的一个元字符出现1次或者多次
  62. # * 在这个量词前面的一个元字符出现0次或者多次
  63. # 例子:
  64. # 1.匹配一个整数:\d+
  65. # 2.匹配一个小数:\d+\.\d+
  66. # 3.匹配整数或者小数: 表达式 \d+(\.\d+)? 括号里面的被量词?问号约束,约束了一组字符的出现次数
  67. # 小练习
  68. # 正则表达式默认都是贪婪匹配
  69. # 贪婪匹配:会尽量多的帮我们匹配内容
  70. # 例子 待匹配字符:李杰和李莲英和李二棍子 正则表达式:李.? 匹配结果:李杰 李莲 李二 匹配到这3条
  71. # 回溯算法下的贪婪匹配
  72. # 例子:待匹配字符:<a>bbbb<a> 正则表达式:<.*> 匹配结果:<a>bbbb<a>
  73. # 非贪婪模式,
  74. # 在量词后面加一个问号,开启非贪婪模式
  75. # 惰性匹配:尽量少的匹配
  76. # 例子:待匹配字符:<a>bbbb<a> 正则表达式:<.*?> 匹配结果:<a> <a> 这两条
  77. # 例子 待匹配字符:李杰和李莲英和李二棍子 正则:李[杰莲英二棍子]* 匹配结果:李杰 李莲英 李二棍子
  78. # 例子 待匹配字符:李杰和李莲英和李二棍子 正则:李[^和]* 匹配结果:李杰 李莲英 李二棍子
  79. # 例子
  80. # 身份证号码是一个长度为15或18个字符的字符串,如果是15位则全部由数字组成,首位不能为0;
  81. # 如果是18位,则前17位全部是数字,末位可能是数字或x
  82. # ^[1-9]\d{14}(\d{2}[x\d])?$
  83. # ^([1-9]\d{16}[\dx]|[1-9]\d{14})$
  84. # 转义符例子
  85. # r'\\n' 匹配 '\n'
  86. # .*?x :爬虫常用 ,表示匹配任意字符,直到遇见x停止
  87. # 练习题
  88. # 1、 匹配一段文本中的每行的邮箱
  89. # http://blog.csdn.net/make164492212/article/details/51656638
  90. #
  91. # 2、 匹配一段文本中的每行的时间字符串,比如:‘1990-07-12’;
  92. #
  93. # 分别取出1年的12个月(^(0?[1-9]|1[0-2])$)、
  94. # 一个月的31天:^((0?[1-9])|((1|2)[0-9])|30|31)$
  95. #
  96. # 3、 匹配qq号。(腾讯QQ号从10000开始) [1,9][0,9]{4,}
  97. #
  98. # 4、 匹配一个浮点数。 ^(-?\d+)(\.\d+)?$ 或者 -?\d+\.?\d*
  99. #
  100. # 5、 匹配汉字。 ^[\u4e00-\u9fa5]{0,}$
  101. #
  102. # 6、 匹配出所有整数

re模块

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. import re
  4. # 1 findall() 匹配所有
  5. ret = re.findall("\d+", 'h2b3123')
  6. print(ret, type(ret)) # ['2', '3123'] <class 'list'>
  7. print("------------ 1 --------------------")
  8. # 分组遇到findall,优先显示分组中匹配到的内容
  9. # ( ) 分组匹配
  10. ret = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com')
  11. print(ret) # ['oldboy']
  12. # 如何取消分组优先? ?:
  13. ret = re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com')
  14. print(ret) # ['www.oldboy.com']
  15. print("------------ 2 --------------------")
  16. # 2 search() 只匹配从左到右的第一个
  17. ret = re.search('\d+','h2b3123')
  18. print(ret) # <_sre.SRE_Match object; span=(1, 2), match='2'>
  19. print(ret.group()) # 2
  20. print("------------ 3 --------------------")
  21. ret = re.search('\d+','aaaab123a1')
  22. if ret:
  23. print(ret.group()) # 123
  24. print("------------ 4 --------------------")
  25. # 3 compile() # 节省时间
  26. # compile 节省时间 一条正则表达式用多次
  27. # '\d+' --> 正则规则 --> python代码 --> 将字符串按照代码执行匹配
  28. ret = re.compile('\d+') # 先写好正则表达式
  29. r = ret.findall('ahkfgilWIVKJBDKvjgheo') # 匹配所有
  30. if r:
  31. print(r)
  32. print("------------ 5 --------------------")
  33. r = ret.search('ahkfgilsk0194750dfjWIVKJBDKvjgheo') # 只匹配从左到右的第一个
  34. if r:
  35. print(r.group()) # 0194750
  36. print("------------ 6 --------------------")
  37. # 4 finditer 节省空间 结果的条数很多的时候
  38. ret = re.finditer('\d+','dskh1040dsvk034fj048d3g5h4j')
  39. for r in ret:
  40. print(r.group())
  41. print("------------ 7 --------------------")
  42. # 练习题
  43. # 匹配标签
  44. s = '<h1>abc</h1>'
  45. ret = re.search('<(\w+)>', s)
  46. print(ret.group())
  47. print("------------ 8 --------------------")
  48. # 分组
  49. s = '<h1>abc</h1>'
  50. ret = re.search('<(\w+)>(.*?)<(/\w+)>', s)
  51. print(ret.group()) # <h1>abc</h1>
  52. print(ret.group(1)) # h1
  53. print(ret.group(2)) # abc
  54. print(ret.group(3)) # /h1
  55. print("------------ 9 --------------------")
  56. # 分组标签
  57. s = '<h1>abc</h1>'
  58. ret = re.search('<(?P<tag>\w+)>(.*?)<(/\w+)>', s)
  59. print(ret.group('tag')) # h1
  60. print("------------ 10 --------------------")
  61. s = '<h1>abc</h1>'
  62. ret = re.search('<(?P<tag1>\w+)>(.*?)</(?P=tag1)>', s)
  63. print(ret) # <_sre.SRE_Match object; span=(0, 12), match='<h1>abc</h1>'>
  64. print(ret.group()) # <h1>abc</h1>
  65. print(ret.group('tag1')) # h1
  66. print("------------ 11 --------------------")
  67. # 还可以在分组中利用?<name>的形式给分组起名字
  68. # 获取的匹配结果可以直接用group('名字')拿到对应的值
  69. ret = re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>", "<h1>hello</h1>")
  70. print(ret.group('tag_name')) # 结果 :h1
  71. print(ret.group()) # 结果 :<h1>hello</h1>
  72. print("------------ 12 --------------------")
  73. # 如果不给组起名字,也可以用\序号来找到对应的组,表示要找的内容和前面的组内容一致
  74. # 获取的匹配结果可以直接用group(序号)拿到对应的值
  75. ret = re.search(r"<(\w+)>\w+</\1>","<h1>hello</h1>")
  76. print(ret.group(1)) # h1
  77. print(ret.group()) # 结果 :<h1>hello</h1>

hashlib模块

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. import hashlib
  4. # 加密模块 摘要算法 一堆加密算法的集合体
  5. # import hashlib
  6. # 给密码加密
  7. # 文件的校验
  8. # hashlib: 将str类型 通过算法 -----> 一串等长度的数字
  9. # 1,不同的字符串 转化成数字肯定不同
  10. # 2,相同的字符串即使在不同的计算机上只要使用相同的加密方式 转化成的数字一定相同
  11. # 3,hashlib加密不可逆,不能破解
  12. # md5加密
  13. # md5加密效率快,通用,安全性相对差
  14. ret = hashlib.md5()
  15. ret.update('好123'.encode('utf-8')) # 51cb75f82eceb17b86f019e01618d75e
  16. print(ret.hexdigest())
  17. print("-------------- 1 ----------------------------------------------")
  18. ret = hashlib.md5()
  19. ret.update('aabbccddeeff'.encode('utf-8')) # d6ce01d2e191f83c4396ee41eed4e076
  20. print(ret.hexdigest())
  21. print("-------------- 2 ----------------------------------------------")
  22. ret = hashlib.md5()
  23. ret.update('1'.encode('utf-8')) # c4ca4238a0b923820dcc509a6f75849b
  24. print(ret.hexdigest())
  25. print("-------------- 3 ----------------------------------------------")
  26. # 撞库
  27. # 经常设置的 111111 000000 123456 password 等等,做了一个对应表,一一对去寻找
  28. ret = hashlib.md5()
  29. ret.update('123456'.encode('utf-8')) # e10adc3949ba59abbe56e057f20f883e
  30. print(ret.hexdigest())
  31. print("-------------- 4 ----------------------------------------------")
  32. # 加盐
  33. # 让你的密码更复杂。
  34. ret = hashlib.md5('hello word!'.encode('utf-8')) # 盐
  35. ret.update('123456'.encode('utf-8')) # cad5c6823564df20c3fb53848a9b84ef
  36. print(ret.hexdigest())
  37. print("-------------- 5 ----------------------------------------------")
  38. # 动态的盐
  39. # username = input('请输入用户名:')
  40. # ret = hashlib.md5(username[::2].encode('utf-8'))
  41. # ret.update('123456'.encode('utf-8')) # 765b4e7ed31b8aa07755d1c24c69d48c
  42. # print(ret.hexdigest())
  43. # sha加密
  44. # sha加密,算法更好 安全性高,效率低,耗时长
  45. ret = hashlib.sha1()
  46. ret.update('gjfds;fldg'.encode('utf-8'))
  47. print(ret.hexdigest()) # 40098e7fbc4d85eba01695315e2dd896bd4d8ebb
  48. print("-------------- 6 ----------------------------------------------")
  49. ret = hashlib.sha256()
  50. ret.update('gjfds;fldg'.encode('utf-8'))
  51. print(ret.hexdigest()) # b3a2d0e194c193ecd04a61a2b28863047b27b7b93c28b5fdab578aeab0f96dd9
  52. print("-------------- 7 ----------------------------------------------")
  53. ret = hashlib.sha512()
  54. ret.update('gjfds;fldg'.encode('utf-8'))
  55. # 9a5eea267dc6b7a7e3eb45f1f9345b735a26dea92787de5f356e87fe4efe635a1d7b27c8f321e9ec87ad03a7eab91d7bfbf7a753da01e3e6dda6a06b272485d6
  56. print(ret.hexdigest())
  57. print("-------------- 8 ----------------------------------------------")
  58. # 文件校验
  59. # 文件较小用下面代码
  60. def check_md5(file):
  61. ret = hashlib.md5()
  62. with open(file, mode='rb') as f1:
  63. ret.update(f1.read())
  64. return ret.hexdigest()
  65. print(check_md5('文件校验1'))
  66. print(check_md5('文件校验2'))
  67. print("-------------- 9 ----------------------------------------------")
  68. # 大文件的校验:
  69. ret1 = hashlib.md5()
  70. ret1.update("a".encode("utf-8"))
  71. print(ret1.hexdigest()) # 0cc175b9c0f1b6a831c399e269772661
  72. ret2 = hashlib.md5()
  73. ret2.update("b".encode("utf-8"))
  74. print(ret2.hexdigest()) # 92eb5ffee6ae2fec3ad71c777531578f
  75. ret3 = hashlib.md5()
  76. ret3.update("a".encode("utf-8"))
  77. ret3.update("b".encode("utf-8"))
  78. print(ret3.hexdigest()) # 187ef4436122d1cc2f40dc2b92f0eba0
  79. print("-------------- 10 ----------------------------------------------")
  80. #
  81. def check_md5(file):
  82. ret = hashlib.md5()
  83. with open(file, mode='rb') as f1:
  84. while 1:
  85. content = f1.read(1024)
  86. if content:
  87. ret.update(content)
  88. else:
  89. break
  90. return ret.hexdigest()
  91. print(check_md5('文件校验1'))
  92. print(check_md5('文件校验2'))

collections模块

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. from collections import namedtuple
  4. from collections import deque
  5. from collections import defaultdict
  6. from collections import Counter
  7. # 1 namedtuple 坐标
  8. point_tuple = namedtuple('point', ['x', 'y'])
  9. p = point_tuple(1, 2)
  10. print(p) # point(x=1, y=2)
  11. print(p[0]) # 1
  12. print(p.x) # 1
  13. print(p.x + p.y) # 3
  14. print("----------- 1 -----------------")
  15. # 2 deque 双向队列
  16. q = deque(['a', 'b', 'c'])
  17. print(q, type(q)) # deque(['a', 'b', 'c']) <class 'collections.deque'>
  18. # 从右边增加值
  19. q.append('x')
  20. q.append('y')
  21. print(q, type(q)) # deque(['a', 'b', 'c', 'x', 'y']) <class 'collections.deque'>
  22. # 从右边删除值
  23. q.pop()
  24. q.pop()
  25. print(q, type(q)) # deque(['a', 'b', 'c']) <class 'collections.deque'>
  26. # 从左边增值
  27. q.appendleft('x')
  28. q.appendleft('y')
  29. print(q, type(q)) # deque(['y', 'x', 'a', 'b', 'c']) <class 'collections.deque'>
  30. # 从左边删除
  31. q.popleft()
  32. ret = q.popleft()
  33. print(ret) # x
  34. print(q, type(q)) # deque(['a', 'b', 'c']) <class 'collections.deque'>
  35. print("----------- 2 -----------------")
  36. # 3 defaultdict 默认值 字典
  37. my_dict = defaultdict(list) # 默认值 为list
  38. my_dict['key1']
  39. my_dict['key2']
  40. my_dict['key3']
  41. print(my_dict) # defaultdict(<class 'list'>, {'key1': [], 'key2': [], 'key3': []})
  42. values = [11, 22, 33, 44, 55, 77, 88, 99, 90]
  43. for val in values:
  44. if val > 66:
  45. my_dict['key1'].append(val)
  46. else:
  47. my_dict['key2'].append(val)
  48. print(my_dict) # defaultdict(<class 'list'>, {'key1': [77, 88, 99, 90], 'key2': [11, 22, 33, 44, 55], 'key3': []})
  49. print("----------- 3 -----------------")
  50. # 构建一个字典,字典的key 从1~100,对应的值都是666
  51. # {1:666,2:666,3:666......}
  52. # 方法1
  53. dic = dict.fromkeys(range(1,101),666)
  54. print(dic)
  55. print("----------- 4 -----------------")
  56. # 方法2
  57. print({key:666 for key in range(1,101)})
  58. print("----------- 5 -----------------")
  59. # 方法3
  60. def func():
  61. return 666
  62. # my_dict = defaultdict(func)
  63. my_dict = defaultdict(lambda : 666)
  64. for i in range(1,101):
  65. my_dict[i]
  66. print(my_dict)
  67. print("----------- 6 -----------------")
  68. # Counter 统计元素个数
  69. # s1 = '电脑电脑sldfjslffdsaf'
  70. s1 = ['电脑','电脑','电脑','电脑','书']
  71. c = Counter(s1)
  72. print(c, type(c)) # Counter({'电脑': 4, '书': 1}) <class 'collections.Counter'>
  73. print(c['f']) # 0
  74. print(c['d']) # 0
  75. print(c['电脑']) # 4
  76. print(dict(c), type(dict(c))) # {'电脑': 4, '书': 1} <class 'dict'>

shutil模块

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. import shutil
  4. # 将文件内容拷贝到另一个文件中
  5. shutil.copyfileobj(open('log1','r'),open('log2','w'))
  6. # 复制文件
  7. shutil.copyfile('log1','log.bak')
  8. # 递归拷贝文件夹
  9. # shutil.copytree('./NB1', './nbb', ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
  10. # 打包和压缩
  11. import time
  12. import tarfile
  13. shutil.make_archive('NB1-%s' % time.strftime('%Y-%m-%d'), 'gztar', root_dir='NB1')
  14. # 解压
  15. t = tarfile.open('NB12019-01-10.tar.gz', 'r')
  16. t.extractall('ttt')
  17. t.close()

目录结构

  1. ├── aaa
  2.    ├── __init__.py
  3. └── m2.py
  4.    ├── bbb
  5.       ├── __init__.py
  6.       └── m3.py 
  7. ├── main.py

main.py文件

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. import sys
  4. # 模块被引用发生了三件事
  5. # 1,创建一个以模块名命名的名称空间
  6. # 2,执行模块代码将模块里面的代码加载到模块名命名的名称空间的内存中
  7. # 3,调用模块内的名字必须通过模块名. 的方式调用
  8. print(sys.path)
  9. print("-------- 1 ------------------------------------")
  10. import aaa
  11. # 包也是模块,他是模块的集合体,所以引用包也会发生三件事情:
  12. # 1,创建一个以包名命名的名称空间。
  13. # 2,执行包中的__init__文件,将__init__里面的代码块加载到以包名明命的名称空间的内存中。
  14. # 3,调用包内的名字必须通过包名. 的方式调用。
  15. print(aaa.x)
  16. print(aaa.y)
  17. aaa.func1()
  18. print(aaa.m2)
  19. print(aaa.m2.xx)
  20. aaa.m2.func2()
  21. print("-------- 2 ------------------------------------")
  22. # 引用bbb这个包怎么做?
  23. print(aaa.bbb)
  24. print(aaa.bbb.oo)
  25. print(aaa.bbb.xxoo)
  26. print("-------- 3 ------------------------------------")
  27. # 想要在此文件引用 bbb包的m3模块 怎么做?
  28. # 第一步 在此文件 import aaa
  29. # 第二步:在aaa 的 __init__ 添加 from aaa import bbb
  30. # 第三步:在bbb 的 __init__ 添加 from aaa.bbb import m3
  31. # 完成以上三步,那么我在此执行文件就可以引用bbb包的m3模块里面的名字
  32. import aaa
  33. aaa.bbb.m3.func3()
  34. print("-------- 4 ------------------------------------")
  35. # 上面的需求满可以这么做:
  36. # from aaa.bbb import func3
  37. # func3()
  38. # 总结:
  39. # from a.b import c .的左边一定是个包,import 后面一定一个具体的名字
  40. # 包里面的__init__ 如果想要引用模块必须是 from ....import ... 不能直接 import
  41. # from a.b.c.d import e.f.g 错误
  42. # from a.b.c.d import e

aaa/__init__.py

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. x = 111
  4. y = 222
  5. def func1():
  6. print(555)
  7. # 如何让 main.py 这个执行文件找到m2文件?
  8. from aaa import m2
  9. # from aaa import *
  10. # 找到bbb这个包
  11. from aaa import bbb

aaa/m2.py

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. xx = '老鼠药'
  4. def func2():
  5. print('in m2 ')

aaa/bbb/__init__.py

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. from aaa.bbb import m3 # 从执行文件的当前目录开始
  4. # from aaa.bbb.m3 import * # 从执行文件的当前目录开始(上面的需求可以这么做)
  5. oo = 'tom'
  6. xxoo = 'www......'

aaa/bbb/m3.py

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. def func3():
  4. print('in m3')

相对导入和绝对导入

目录结构

  1. lichengguo@lichengguodeMacBook-Pro day16 模块与包 random % tree
  2. ├── main.py
  3. ├── nb
  4.    ├── __init__.py
  5.    ├── m1.py
  6.    └── m2.py

main.py

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. # 绝对导入: 以执行文件的sys.path为起始点开始导入,称之为绝对导入
  4. # 优点: 执行文件与被导入的模块中都可以使用
  5. # 缺点: 所有导入都是以sys.path为起始点,导入麻烦
  6. # import nb
  7. # nb.f1()
  8. # nb.f2()
  9. # nb.f3()
  10. # nb.f4()
  11. # 相对导入: 参照当前所在文件的文件夹为起始开始查找,称之为相对导入
  12. # 符号: .代表当前所在文件的文件加,..代表上一级文件夹,...代表上一级的上一级文件夹
  13. # 优点: 导入更加简单
  14. # 缺点: 只能在导入包中的模块时才能使用
  15. from nb import m1
  16. from nb import m1
  17. m1.f1()
  18. m1.f2()

nb/__init__.py

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. # 绝对导入
  4. # from nb.m1 import f1, f2
  5. # from nb.m2 import f3, f4
  6. # 相对导入
  7. from .m1 import f1, f2
  8. from .m2 import f3, f4

nb/m1.py

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. def f1():
  4. print('in f1')
  5. def f2():
  6. print('in f2')

nb/m2.py

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. def f3():
  4. print('in f3')
  5. def f4():
  6. print('in f4')

练习题1

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. # 1、计算两个格式化时间之间差了多少年月日时分秒
  4. # 例如 '1997-10-1 08:00:00' 和 '1997-10-2 09:00:00'
  5. import time
  6. def diff_time(t1, t2):
  7. t1_struct = time.strptime(t1,'%Y-%m-%d %H:%M:%S')
  8. t1_stamp = time.mktime(t1_struct)
  9. t2_struct = time.strptime(t2,'%Y-%m-%d %H:%M:%S')
  10. t2_stamp = time.mktime(t2_struct)
  11. if t1_stamp > t2_stamp:
  12. diff_t = t1_stamp - t2_stamp
  13. else:
  14. diff_t = t2_stamp - t1_stamp
  15. diff_t_struct = time.gmtime(diff_t)
  16. print('两个时间相差了 [%s]年 [%s]月 [%s]日 [%s]时 [%s]分 [%s]秒'
  17. % (diff_t_struct.tm_year-1970, diff_t_struct.tm_mon-1,
  18. diff_t_struct.tm_mday-1, diff_t_struct.tm_hour,
  19. diff_t_struct.tm_min, diff_t_struct.tm_sec))
  20. t1 = '1997-10-1 08:00:00'
  21. t2 = '1997-10-2 09:00:00'
  22. diff_time(t1, t2)
  23. print("------------------- 1 -----------------------------------------")
  24. # 2、计算当前时间所在月1号的时间戳
  25. import time
  26. def get_time():
  27. now_t = time.strftime('%Y-%m')
  28. uct_t = time.strptime(now_t, '%Y-%m')
  29. stamp_t = time.mktime(uct_t)
  30. return stamp_t
  31. ret = get_time()
  32. print(ret) # 1617206400.0
  33. # print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(ret))) # 2021-04-01 00:00:00
  34. print("------------------- 2 -----------------------------------------")
  35. # 3、生成一个6位随机验证码(包含数字和大小写字母)
  36. import random
  37. def get_code(n=6, flag=True):
  38. code = ''
  39. for i in range(n):
  40. selectd = random.randint(0, 9)
  41. if flag:
  42. alp = random.randint(65, 90)
  43. selectd = random.choice([selectd, chr(alp)])
  44. code += str(selectd)
  45. return code
  46. ret = get_code()
  47. print(ret)
  48. print("------------------- 3 -----------------------------------------")
  49. # 4、发红包、制定金额和个数,随机分配红包金额
  50. def hb(num, money):
  51. # 定义空列表用来存储抽奖金额
  52. lst = []
  53. # 金额乘以100,便于计算,后续加入到列表在除以100
  54. money = int(money * 100)
  55. # 判断传递参数的合法性
  56. if type(num) is int and num >=1 and (type(money) is int or type(money) is float):
  57. # for循环应该比num少一次,例如2个红包个数,for循环1次就可以
  58. for i in range(1, num):
  59. # 保证不出现抽中0元的现象
  60. p = random.randint(1, money - (num - i))
  61. lst.append(p / 100)
  62. # 需要减去已经抽取的红包金额
  63. money = money - p
  64. else:
  65. # 循环结束了,把剩余的红包总金额放入到一个红包内
  66. lst.append(money / 100)
  67. return lst
  68. else:
  69. print('参数有误!')
  70. ret = hb(3, 0.04)
  71. print(ret)
  72. print("------------------- 4 -----------------------------------------")
  73. # 5、分别列出给定目录下所有的文件和文件夹
  74. import os
  75. def lis_file_path(path):
  76. dir_list = []
  77. file_list = []
  78. # 拼接路径
  79. ret_list = os.listdir(r'%s' % path)
  80. for i in ret_list:
  81. ret = os.path.join(path + '/%s' % i)
  82. if os.path.isfile(ret):
  83. file_list.append(i)
  84. elif os.path.isdir(ret):
  85. dir_list.append(i)
  86. return dir_list,file_list
  87. ret = lis_file_path(r'/tmp')
  88. print('目录:', ret[0])
  89. print('文件:', ret[1])
  90. print("------------------- 5 -----------------------------------------")
  91. # 6、获取当前文件所在目录
  92. import os
  93. ret = os.path.abspath(__file__)
  94. print(os.path.dirname(ret))
  95. print("------------------- 6 -----------------------------------------")
  96. # 7、在当前目录下创建一个文件夹、在这个文件夹下创建一个文件
  97. import os
  98. def mk():
  99. # 获取被运行的PY文件绝对目录
  100. now_abs_dir = os.path.dirname(os.path.abspath(__file__))
  101. # 拼接路径
  102. ret_dir = os.path.join(now_abs_dir + '/new_dir')
  103. # 创建一个文件夹
  104. if not os.path.isdir(ret_dir):
  105. os.mkdir(ret_dir)
  106. # 拼接路径
  107. ret_file = os.path.join(ret_dir + '/test.txt')
  108. # 创建一个文件
  109. with open(r'%s' % ret_file, encoding='utf-8', mode='w') as f:
  110. pass
  111. mk()
  112. print("------------------- 7 -----------------------------------------")
  113. # 8、计算某路径下所有文件和文件夹的总大小
  114. import os
  115. # 文件总大小
  116. total_size = 0
  117. def lis_file_path(path):
  118. global total_size
  119. # 获取指定目录下的文件和子目录,返回一个列表
  120. ret_list = os.listdir(r'%s' % path)
  121. for i in ret_list:
  122. # 拼接路径
  123. ret = os.path.join(path + '/%s' % i)
  124. # 如果是文件夹继续递归
  125. if os.path.isdir(ret):
  126. lis_file_path(ret)
  127. # 如果是文件就直接计算大小,算入总值
  128. elif os.path.isfile(ret):
  129. size = os.path.getsize(ret)
  130. total_size += size
  131. return "%s%s" % (total_size/1024/1024, "MB")
  132. ret = lis_file_path('/Users/lichengguo/Documents/98-Python/python3-02/')
  133. print(ret)
  134. print("------------------- 8 -----------------------------------------")

练习题2

  1. #!/usr/bin/env python3
  2. # author:Alnk(李成果)
  3. """
  4. 需求:
  5. 实现加减乘除及拓号优先级解析
  6. 用户输入
  7. 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )
  8. 等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式
  9. 注意:不能调用eval等类似功能偷懒实现
  10. """
  11. import re
  12. def calc(s):
  13. """计算加减乘除"""
  14. # 去掉空格
  15. s = s.replace(' ', '')
  16. # 替换运算符号
  17. s = s.replace('--', '+').replace('++', '+').replace('-+', '-').replace('+-', '-')
  18. # 计算乘除
  19. while re.search('[.\d]+[*/]+[-+]?[.\d]+', s):
  20. # 匹配第一个乘除公式
  21. res = re.search('[.\d]+[*/]+[-+]?[.\d]+', s).group()
  22. # 判断乘除
  23. if res.count('*'):
  24. res_list = res.split('*')
  25. ret = float(res_list[0]) * float(res_list[1])
  26. else:
  27. res_list = res.split('/')
  28. ret = float(res_list[0]) / float(res_list[1])
  29. # 把结果替换回原来的公式中,并且替换运算符
  30. s = s.replace(res, str(ret)).replace('--', '+').replace('++', '+').replace('-+', '-').replace('+-', '-')
  31. # 计算加减
  32. # 找到所有的 正数或者负数,生成一个列表
  33. s_list = re.findall('[-]?[.\d]+', s)
  34. sum = 0
  35. # 循环列表,都做加法(减法可以看作加一个负数)
  36. for i in s_list:
  37. sum += float(i)
  38. return sum
  39. def strip_kuohao(s):
  40. # 去掉空格
  41. s = s.replace(' ', '')
  42. # 替换运算符号
  43. s = s.replace('--', '+').replace('++', '+').replace('-+', '-').replace('+-', '-')
  44. # 匹配最里层的括号
  45. while re.search('\([^\(\)]+\)', s):
  46. # 替换运算符号
  47. s = s.replace('--', '+').replace('++', '+').replace('-+', '-').replace('+-', '-')
  48. # 获取匹配到的最里层的括号公式
  49. kuohao_res = re.search('\([^\(\)]+\)', s).group()
  50. # 去掉括号,传入calc函数进行加减乘除运算
  51. kuohao_res_strip = kuohao_res.strip('(,)')
  52. ret = calc(kuohao_res_strip)
  53. # 结果替换到原来的公式中
  54. s = s.replace(kuohao_res, str(ret))
  55. else:
  56. # 最后没有括号的公式还要进行一次加减乘除运算,算出最后的结果
  57. ret = calc(s)
  58. s = s.replace(s, str(ret))
  59. return s
  60. s = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
  61. ret = strip_kuohao(s)
  62. print(ret)
  63. print(eval(s))

Python语言系列-05-模块和包的更多相关文章

  1. Python 入门基础13 --模块与包

    本节内容: 一.模块及使用 1.模块及使用 2.起别名.from导入 3.自执行与模块 二.包的使用 2.1 包中模块的使用:import 2.2 包的嵌套 2.3 包中模块的使用:from ...i ...

  2. 2015/9/15 Python基础(12):模块和包

    模块是用来组织 Python 代码的方法,而包则是用来组织模块的. 当代码量很大时,我们一般会把代码分成几个有组织的代码段,然后每个代码段之间有一定的联系.代码单之间是共享的,所以Python允许调入 ...

  3. python(33)- 模块与包

    一 模块 1 什么是模块? 一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 2 为何要使用模块? 如果你退出python解释器然后重新进入,那么你之前定义的函 ...

  4. Python Revisited Day 05(模块)

    目录 5.1 模块与包 5.1.1 包 5.2 Python 标准库概览 5.2.1 字符串处理 io.StringIO 类 5.2.3 命令行设计 5.2.4 数学与数字 5.2.5 时间与日期 5 ...

  5. python之旅:模块与包

    一.模块介绍 前言:引用廖雪峰大神的,说的很好!!! 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放 ...

  6. Python基础入门(模块和包)

    1 模块 1.1 什么是模块 在 Python 中,一个 .py 文件就称之为一个模块(Module). 我们学习过函数,知道函数是实现一项或多项功能的一段程序 .其实模块就是函数功能的扩展.为什么这 ...

  7. Python学习笔记 - day9 - 模块与包

    模块与包 一个模块就是一个包含了Python定义和声明的文件,文件名就是模块名加上.py的后缀,导入一个py文件,解释器解释该py文件,导入一个包,解释器解释该包下的 __init__.py 文件,所 ...

  8. 【python基础语法】模块和包管理,文件的操作(第8天课堂笔记)

    ''' 模块和包管理 模块和包的定义: 模块:模块是一个Python文件,以.py结尾,包含了Python对象定义和Python语句 包:Python中的包就是一个包含__init__.py文件的目录 ...

  9. Python语言学习:模块

    一.模块 1. 模块(Module):以.py结尾的文件,包含python对象定义和python语句.使代码段更容易理解和使用. 模块分为两种:标准库(直接导入的库)和第三方库(需要下载安装的库). ...

随机推荐

  1. 对象池技术和通用实现GenericObjectPool

    对象池技术其实蛮常见的,比如线程池.数据库连接池 他们的特点是:对象创建代价较高.比较消耗资源.比较耗时: 比如 mysql数据库连接建立就要先建立 tcp三次握手.发送用户名/密码.进行身份校验.权 ...

  2. Centos-Springboot项目jar包自启动

    CentOS环境下部署Springboot项目的jar包开机自启动. 部署环境 Centos 7.5 Springboot 2.1.x 操作步骤 修改pom 在pom.xml文件中<plugin ...

  3. 增强采样软件PLUMED的安装与使用

    技术背景 增强采样(Enhanced Sampling)是一种在分子动力学模拟中常用的技术,其作用是帮助我们更加快速的在时间轴上找到尽可能多的体系结构及其对应的能量.比如一个氢气的燃烧反应,在中间过程 ...

  4. 深入理解 SynchronizationContext

    深入理解 SynchronizationContext 目录 深入理解 SynchronizationContext SynchronizationContext(后续以SC简称) 是什么? 1.1 ...

  5. 深入浅出图神经网络 第6章 GCN的性质 读书笔记

    第6章 GCN的性质 第5章最后讲到GCN结束的有些匆忙,作为GNN最经典的模型,其有很多性质需要我们去理解. 6.1 GCN与CNN的区别与联系 CNN卷积卷的是矩阵某个区域内的值,图卷积在空域视角 ...

  6. ESP32构建系统 (传统 GNU Make)

    概述: 一个 ESP-IDF 项目可以看作是多个不同组件的集合,ESP-IDF 可以显式地指定和配置每个组件.在构建项目的时候,构建系统会前往 ESP-IDF 目录.项目目录和用户自定义目录(可选)中 ...

  7. [刘阳Java]_Spring AOP入门_第7讲

    AOP技术个人认为是能够完善(改善)面向对象编程OOP.为什么这么说,我们得先从AOP的概念说起,然后通过一段简单的例子加以佐证.这样子大家就可以慢慢地了解AOP 1. AOP概念 AOP为Aspec ...

  8. Spring Boot 2.x基础教程:使用Elastic Job实现定时任务

    上一篇,我们介绍了如何使用Spring Boot自带的@Scheduled注解实现定时任务.文末也提及了这种方式的局限性.当在集群环境下的时候,如果任务的执行或操作依赖一些共享资源的话,就会存在竞争关 ...

  9. 每天五分钟Go - Map

    map的定义 var m map[type]type fmt.Println(m) 此种方法定义的m为nil //打印的结果为: map[] map的创建 1.使用make创建 var m1 = ma ...

  10. 【排序+模拟】魔法照片 luogu-1583

    题目描述 一共有n(n≤20000)个人(以1--n编号)向佳佳要照片,而佳佳只能把照片给其中的k个人.佳佳按照与他们的关系好坏的程度给每个人赋予了一个初始权值W[i].然后将初始权值从大到小进行排序 ...