python 解决动态的定义变量名,并给其赋值的方法(大数据处理)


Posted in Python onNovember 10, 2018

最近消费kafka数据到磁盘的时候遇到了这样的问题:

需求:每天大概有1千万条数据,每条数据包含19个字段信息,需要将数据写到服务器磁盘,以第二个字段作为大类建立目录,第7个字段作为小类配合时间戳作为文件名,临时文件后缀tmp,当每个文件的写入条数(可配置,比如100条)达到要求条数时,将后缀tmp改为out。

问题:大类共有30个,小类不计其数而且未知,比如大类为A,小类为a,时间戳为20180606095835234,则A目录下的文件名为20180606095835234_a.tmp,这样一来需要在此文件写满100条时,更新时间戳生成第二个文件名,如果此时有1000个文件都在写则需要有1000个时间戳,和1000个计数器记录每个文件当前的条数,如果分别定义1000个变量显然是不划算的,

尝试:中间过程想到了动态定义变量名,即

定义第七个字段:seven = data.split('|')[7]

定义文件名:filename = time_stamp + '_' + seven+'.tmp',

定义文件计数器:seven + ‘_num' = 0

定义文件时间戳:seven + '_stamp' = time.time( )

想法其实是没问题的,但是这里用到了一个不常用的语法:用一个变量名和一个字符串拼接出来一个新的变量名,并继续赋值(不知道我的表述是否清楚),试过了用local()函数、global()函数、exec()函数都没有达到预期效果,也许是把问题想的太复杂了

解决:最后使用三个字典将这个问题完美解决,

定义一个字典用来存计数器,字典的每一个键对应一个文件名,值对应当前计数,并实时更新;

定义一个字典用来存时间戳,键对应一个文件名,值对应时间戳,达到100条就更新一次;

定义一个字典用来存大类,键对应代号,值对应分类;

局部功能代码如下:

def kafka_to_disk():
 print('启动前检测上次运行时是否存在意外中断的数据文件......')
 print('搜索最近一次执行脚本产生的时间目录......')
 # 待处理临时文件列表
 tmp_list = []
 try:
  for category_dir in os.listdir(local_file_path):
   if len(os.listdir(local_file_path+os.sep+category_dir)) > 0:
    for file in os.listdir(local_file_path+os.sep+category_dir):
     if suffix in file:
      tmp_list.append(local_file_path+os.sep+category_dir+os.sep+file)
  # print('上次运行程序产生的临时文件有---{}'.format(tmp_list))
 except Exception as e:
  pass
 if len(tmp_list) == 0:
  print('未扫描任何残留临时文件')
 else:
  print('开始修复残留临时文件......')
 tmp_num = 0
 for tmp in tmp_list:
  os.rename(tmp, tmp.split('.')[0]+'.out')
  tmp_num += 1
 print('本次启动共修复残留临时文件★★★★★-----{}个-----★★★★★'.format(tmp_num))
 
 category_poor = {
  '1': 'news', '2': 'weibo', '3': 'weixin', '4': 'app', '5': 'newspaper', '6': 'luntan',
  '7': 'blog', '8': 'video', '9': 'shangji', '10': 'shangjia', '11': 'gtzy', '12': 'zfztb',
  '13': 'gyfp', '14': 'gjz', '15': 'zfxx', '16': 'ptztb', '17': 'company', '18': 'house',
  '19': 'hospital', '20': 'bank', '21': 'zone', '22': 'express', '23': 'zpgw', '24': 'zscq',
  '25': 'hotel', '26': 'cpws', '27': 'gxqy', '28': 'gpjj', '29': 'dtyy', '30': 'bdbk'}
 
 time_stamp = utils.get_time_stamp() # 初始化毫秒级时间戳 : 20180509103015125
 consumer = KafkaConsumer(topic, group_id=group_id, auto_offset_reset=auto_offset_reset, bootstrap_servers=eval(bootstrap_servers))
 print('连接kafka成功,数据筛选中......')
 file_poor = {}       # 子类池用于文件计数器
 time_stamp_poor = {}     # 子类时间戳池,用于触发文件切换
 time_stamp = utils.get_time_stamp()  # 初始化毫秒级时间戳 :20180509103015125
 for message in consumer:
  # 提取第8个字段自动匹配目录进行创建
  if message.value.decode().split('|')[1] in category_poor:
   category = category_poor[message.value.decode().split('|')[1]]
  else:
   print(message.value.decode())
   continue
  category_dir = local_file_path + os.sep + category
  if not os.path.exists(category_dir):
   os.makedirs(category_dir)
  # 提取第2个字段,用于生成文件名
  if message.value.decode().split('|')[7] in time_stamp_poor:
   shot_file_name = time_stamp_poor[message.value.decode().split('|')[7]] + '_' + message.value.decode().split('|')[7]
  else:
   shot_file_name = time_stamp + '_' + message.value.decode().split('|')[7]
  file_name = category_dir + os.sep + shot_file_name + '.tmp'
 
  # 给每一个文件设定一个计数器
  if message.value.decode().split('|')[7] not in file_poor:
   file_poor[message.value.decode().split('|')[7]] = 0
 
  with open(file_name, 'a', encoding='utf-8')as f1:
   f1.write(message.value.decode())
   file_poor[message.value.decode().split('|')[7]] += 1
 
  # 触发切换文件的操作,用时间戳生成第二文件名
  if file_poor[message.value.decode().split('|')[7]] == strip_number:
   time_stamp_poor[message.value.decode().split('|')[7]] = utils.get_time_stamp()
   file_poor[message.value.decode().split('|')[7]] = 0

以上这篇python 解决动态的定义变量名,并给其赋值的方法(大数据处理)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python利用正则表达式匹配并截取指定子串及去重的方法
Jul 30 Python
合并百度影音的离线数据( with python 2.3)
Aug 04 Python
python爬取m3u8连接的视频
Feb 28 Python
对Python中range()函数和list的比较
Apr 19 Python
解决Python获取字典dict中不存在的值时出错问题
Oct 17 Python
pandas DataFrame索引行列的实现
Jun 04 Python
matplotlib命令与格式之tick坐标轴日期格式(设置日期主副刻度)
Aug 06 Python
使用pytorch实现可视化中间层的结果
Dec 30 Python
pycharm中导入模块错误时提示Try to run this command from the system terminal
Mar 26 Python
PyCharm上安装Package的实现(以pandas为例)
Sep 18 Python
详解Python中第三方库Faker
Sep 25 Python
pytorch中的model=model.to(device)使用说明
May 24 Python
在Python中定义一个常量的方法
Nov 10 #Python
python 定义n个变量方法 (变量声明自动化)
Nov 10 #Python
浅谈python连续赋值可能引发的错误
Nov 10 #Python
Linux下安装python3.6和第三方库的教程详解
Nov 09 #Python
Python2和Python3.6环境解决共存问题
Nov 09 #Python
python3 面向对象__类的内置属性与方法的实例代码
Nov 09 #Python
python 不同方式读取文件速度不同的实例
Nov 09 #Python
You might like
PHP字符串处理的10个简单方法
2010/06/30 PHP
PHP获取当前日期及本周一是几月几号的方法
2017/03/28 PHP
php7基于递归实现删除空文件夹的方法示例
2017/06/15 PHP
Javascript 学习笔记 错误处理
2009/07/30 Javascript
优化javascript的执行速度
2010/01/23 Javascript
javascript学习笔记(一) 在html中使用javascript
2012/06/18 Javascript
jQuery实现判断滚动条到底部
2015/06/23 Javascript
js制作带有遮罩弹出层实现登录注册表单特效代码分享
2015/09/05 Javascript
javascript实现动态标签云
2015/10/16 Javascript
深入浅析JavaScript中prototype和proto的关系
2015/11/15 Javascript
AngularJS中使用HTML5手机摄像头拍照
2016/02/22 Javascript
jQuery实现页面点击后退弹出提示框的方法
2016/08/24 Javascript
jQuery  ready方法实现原理详解
2016/10/19 Javascript
node.js中实现kindEditor图片上传功能的方法教程
2017/04/26 Javascript
使用use注册Vue全局组件和全局指令的方法
2018/03/08 Javascript
vue中的ref和$refs的使用
2018/11/22 Javascript
js实现页面多个日期时间倒计时效果
2019/06/20 Javascript
vue+elementUI组件table实现前端分页功能
2020/11/15 Javascript
Js实现复选框的全选、全不选反选功能代码实例
2020/02/28 Javascript
[43:14]Liquid vs Optic 2018国际邀请赛淘汰赛BO3 第二场 8.21
2018/08/22 DOTA
Python守护进程和脚本单例运行详解
2017/01/06 Python
深入理解Python中range和xrange的区别
2017/11/26 Python
python sys.argv[]用法实例详解
2018/05/25 Python
基于python3实现socket文件传输和校验
2018/07/28 Python
python使用插值法画出平滑曲线
2018/12/15 Python
python实现二级登陆菜单及安装过程
2019/06/21 Python
Django的性能优化实现解析
2019/07/30 Python
Python实现平行坐标图的绘制(plotly)方式
2019/11/22 Python
python矩阵运算,转置,逆运算,共轭矩阵实例
2020/05/11 Python
乌克兰在线电子产品商店:MTA
2019/11/14 全球购物
数据库方面面试题
2012/04/22 面试题
市优秀教师事迹材料
2014/02/05 职场文书
新教师培训方案
2014/06/08 职场文书
党委班子剖析材料
2014/08/21 职场文书
领导干部学习十八届五中全会精神心得体会
2016/01/05 职场文书
MySQL提升大量数据查询效率的优化神器
2022/07/07 MySQL