python.struct helper class

8 篇文章 0 订阅
5 篇文章 0 订阅

 

/*!
python struct helper class
version    : 0.01 
created by : andrew.wu (erpingwu@gmail.com)
created on : 2009/05/23
url        : http://blog.oolanguage.com/erpingwu/python-struct-module-helper-class/
*/


python struct 是一个很好用的 module ,能够很方便的处理 c struct, 但转换一个 c struct 到格式化字符串的工作有些繁琐.一个有效率的程序员应该是一个会偷懒的程序员,繁琐的工作应该尽量自动化.
c struct 可以写得很复杂,但大部分时候还是相对规范,那么先做一个简单的版本
以解释大智慧-Internet版的日线数据来做一个实例

	struct DZHDay{ 
		unsigned int trade_date;  // 日期,转换为十进制即可 
		unsigned int open_price;  // 开盘,除以1000 
		unsigned int high_price;  // 最高,除以1000 
		unsigned int low_price;   // 最低,除以1000 
		unsigned int close_price; // 收盘,除以1000 
		unsigned int turn_volume;// 成交额,除以10 
		unsigned int trading_volume ; // 成交量 
		unsigned int private_investor_line; // 散户线
		unsigned int unknown1;  // 
		unsigned int unknown2;  // 
	};


首先,需要python能够自动取得struct的相关信息, 这里没有自己去实现什么,什么都自己做那就不是提高效率了,而是给自己找麻烦. 网上找到一个 CppHeaderParser.py 正好可以用来完成这个工作, 只需要稍做修改.

line 427:  if (tok.value == 'class' or tok.value == 'struct'): 
line 452:  elif (self.nameStack[0] == "class" or self.nameStack[0] == "struct"):


下面就贴代码了,看代码比什么都来得清楚
t.py

# -*- coding: utf-8-*-
import os
from struct import *
from andrew.struct_helper import *
import binascii

dzh_day = '''
	struct DZHDay{ 
		unsigned int trade_date;  // 日期,转换为十进制即可 
		unsigned int open_price;  // 开盘,除以1000 
		unsigned int high_price;  // 最高,除以1000 
		unsigned int low_price;   // 最低,除以1000 
		unsigned int close_price; // 收盘,除以1000 
		unsigned int turn_volume;// 成交额,除以10 
		unsigned int trading_volume ; // 成交量 
		unsigned int private_investor_line; // 散户线
		unsigned int unknown1;  // 
		unsigned int unknown2;  // 
	};
	''';
	
import unittest
class Tests(unittest.TestCase):
	def setUp(self):
		self.sh = StructHelper();
		self.sh.parse(dzh_day, "DZHDay");
		pass;
	def tearDown(self):
		pass
	def testOne(self):
		f = open(r"600050.day", 'rb');	
		data = f.read();
		f.close()		
		nt = self.sh.namedtuple._make(unpack(self.sh.format_string, 
			data[0 : self.sh.unpack_size]));
		#print nt
		self.assertEqual(nt.trade_date, 20090521)
	def testTwo(self):
		#f = open(r"C:/dzh/DATA/SHase/Day/600388.day", 'rb');
		f = open(r"600050.day", 'rb');
		data = f.read();
		f.close()	
		#print binascii.b2a_hex(data)
		for index in range(0,  len(data) / self.sh.unpack_size ):
			nt = self.sh.namedtuple._make( unpack_from( self.sh.format_string, 
				data, self.sh.unpack_size*index) );			
			print "/n", nt	
		pass;
	pass

def main():
    unittest.main()

if __name__ == '__main__':
    main()


struct_helper.py

# struct helper class
# version      : 0.01 v  
# created by : andrew.wu (erpingwu@gmail.com)
# created on : 2009/05/23

import os
from struct import *
from collections import namedtuple
from  CppHeaderParser import *

class StructHelper():
	_struct_format_table = {
		'pad byte':'x',
		'char':'c',
		'signed char':'b',
		'unsigned char':'B',
		'bool':'?',
		'BOOL':'?',
		'short':'h',
		'unsigned short':'H',
		'int':'i',
		'unsigned int':'I',
		'long':'l',
		'unsigned long':'L',
		'long long':'q',
		'unsigned long long':'Q',
		'float':'f',
		'double':'d',
		'char[]':'s',
		'void *':'P'
	}
	
	def type_to_fmt(self, type):
		return self._struct_format_table[type];
		pass;
	
	def parse(self, code, struct_name):
		self.format_string = ""
		self.named_string = ""
		cpp_header = CppHeader(code , argType = "string")
		properties = cpp_header.classes[struct_name]["properties"]["private"]
		for p in properties:
			self.format_string += self.type_to_fmt(p["type"])
			self.named_string += p["name"] + " "
		self.unpack_size = calcsize(self.format_string)
		self.namedtuple = namedtuple(struct_name, self.named_string)
		pass;
		
	pass;



output
.
DZHDay(trade_date=20090521, open_price=6400, high_price=6410, low_price=6180, cl ose_price=6240, turn_volume=2085205, trading_volume=3334743, private_investor_li ne=373549, unknown1=4857, unknown2=2136735744)
DZHDay(trade_date=20090522, open_price=6210, high_price=6290, low_price=6170, cl ose_price=6260, turn_volume=1023114, trading_volume=1639956, private_investor_li ne=385, unknown1=4873, unknown2=0) .
----------------------------------------------------------------------
Ran 2 tests in 0.000s OK


相关引用
CppHeaderParser-1.05 http://sourceforge.net/projects/cppheaderparser/
PLY (Python Lex-Yacc) 3.2 http://www.dabeaz.com/ply/
Python 2.6 http://www.python.org/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值