利用python函数装饰器解决天软交互编码问题

天软python交互编码问题的解决

  • 前言
  • 主要功能与思路说明
  • 代码
    • 使用范例
    • 核心代码

前言

天软TSL取数稳定高效,第三方交互也很多。只是目前python与天软TSL的交互模块,默认返回编码gbk,导致很多时候看到一大堆乱码,每次见到中文decode也比较麻烦,给出解决这个问题的一个思路。

主要功能与思路说明

  • 编码:天软返回的结果是基础数据类型,遍历一下利用tostry得到定义串,eval一下即可。
  • 函数注释:默认提供的两个接口ts.RemoteExecutets.RemoteCallFunc都没有函数注释,利用函数装饰器,添加中文说明。
  • 日期转换:经常需要将天软的日期与整形日期在python中进行转换,利用函数装饰器提供带缓存的两个对应接口,ts.tsdatetimetopyts.tsRdatetopy

代码

使用范例

# 与天软交互:ts,
# 自动将gbk编码转化为utf-8
import sys
sys.path.append(r'E:\桌面space\临时数据\python\个人自定义模块')
from MYtinysoft import ts # MYtinysoft.py见核心代码段

核心代码

# MYtinysoft.py
import datetime
import sys

import itertools
from inspect import Signature,Parameter
import re

sys.path.append('C:\\Program Files\\Tinysoft\\Analyse.NET\\') ###更改此处
import TSLPy3 as ts
if __name__ == '__main__':
    data = ts.RemoteExecute('return 1;', { })
    Stockname = ts.RemoteCallFunc('stockname', ['SH000001'], { })


RemoteExecute_doc = '''
    RemoteExecute(ExecString:String;SysParam:dict): 
        函数说明:
        =========
            远程执行 ts 语句 
    
        参数说明:
        =========    
            ExecString 天软语句的字符串; 
            SysParam: 天软执行的系统参数,字典类型,参考系统参数简介
        
        返回说明: 
        =========    
        Tuple(ErrNo,Result,ErrMsg) 
            ErrNo : 错误标志 0成功, 
            Result 结果,  
            ErrMsg 如果错误的时候的信息
    '''

RemoteCallFunc_doc = '''
    RemoteCallFunc(Func:String;Args:list|tuple;SysParam:dict):Tuple(ErrNo,Result,ErrMsg); 
        函数说明:
        =========
            远程执行 ts 函数
        
        参数说明:
        =========
            Func 天软函数名; 
            Args:天软函数的参数列表,类型为 python 的数组,每个元素对应天软函数的一个参数 
              注意:如果天软函数需要的参数为表达式类型,传递会失败,需要另外想办法.比如重新封装函数;
                   然后传入字符串,将字符串转换为天软的表达式类型 
            SysParam: 天软执行的系统参数,字典类型,参考系统参数简介 

        返回说明: 
        =========    
        Tuple(ErrNo,Result,ErrMsg) 
            ErrNo : 错误标志 0成功, 
            Result 结果,  
            ErrMsg 如果错误的时候的信息
    '''
from functools import lru_cache

@lru_cache(250)
def tsdatetimetopy(tsldatetime):
    '''
    tsdatetimetopy(tsldatetime:float);
        函数说明:转化天软时间为python的datetime
    范例:
       >>> tsdatetimetopy(41456)
       datetime.datetime(2013, 7, 1, 0, 0)
    '''
    dtimetuple = ts.DecodeDateTime(tsldatetime)
    return datetime.datetime(*dtimetuple)

@lru_cache(250)
def tsRdatetopy(tsRdate):
    """
    tsdatetopy(tslRdate:int);
        函数说明:转化天软报告期转为python的datetime
        范例:
            >>> tsRdatetopy(20180101)
            datetime.date(2018, 1, 1)
    """
    return datetime.date(tsRdate // 10000 , (tsRdate % 10000)//100,tsRdate %100)

def getsig(doc):
    parms = []
    for v1 in itertools.islice(re.finditer("\((.*?)\)",doc),1):
        for v2 in v1.groups()[0].split(";"):
            ll = v2.split(":")
            parms.append(Parameter(ll[0],Parameter.POSITIONAL_OR_KEYWORD,annotation=ll[1]))
    return Signature(parms)


# 自定义函数装饰器
from functools import wraps
def Mymedic(func,doc):
    @wraps(func)
    def wrapper(*args, **kwargs):
        return VariableFromTsl(func(*args, **kwargs));
    # 指定注释
    wrapper.__doc__ = doc
    # 自定义参数列表
    wrapper.__signature__ = getsig(doc)
    return wrapper


def VariableFromTsl(r0):
    return tsbytestostr(r0)

# 保持结构不变
def tsbytestostr(data, bytes2encoing = 'gbk'):
    if isinstance(data,(tuple, list)):
        return type(data)(tsbytestostr(v,bytes2encoing) for v in data)
    elif isinstance(data,dict):
        return {tsbytestostr(k,bytes2encoing):tsbytestostr(v,bytes2encoing) 
                    for k,v in data.items()}
    elif isinstance(data,bytes):  
        return data.decode(bytes2encoing) 
    else: 
        return data

if True:
    ts.RemoteExecute = Mymedic(ts.RemoteExecute,RemoteExecute_doc)
    ts.RemoteCallFunc = Mymedic(ts.RemoteCallFunc,RemoteCallFunc_doc)

ts.tsdatetimetopy = tsdatetimetopy
ts.tsRdatetopy = tsRdatetopy

你可能感兴趣的:(天软TSL)