matlab调用python库函数和自定义脚本函数

作者:matrix 发布时间:2019年7月15日星期一 分类:零零星星

本来只是想获取字符串的MD5hash值,结果发现麻烦。首先去mathworks找到的DataHash,GetMD5这些函数要么无法使用,要么就是计算出来的md5值是错误的,反正达不到效果。
刚开始以为mathworks的代码必须登录账户才能下载,现在才发现,点击Overview旁边的Functions选项卡就能看到源代码。 😂
图片4928-matlab MD5函数
当初就算是找到了一些函数也是不能使用,最后还是使用python库来解决。好在matlab对python的调用非常简单。直接使用py库就好了,唯一的问题就是有些python的语法和matlab不同,比如切片[:::]操作这些。

直接调用python内置函数

计算字符串md5函数

使用python的hashlib库进行操作

function[re]=md5(str)
    %{
        依赖python进行md5 hash
    %}
    m2 = py.hashlib.md5();
    m2.update(py.str(str).encode('utf-8'));
    re = char(m2.hexdigest());

说明:
此函数依赖python环境,确保系统中有安装。
兼容Linux,Mac,Windows

最后char函数是将py.str类型转换为matlab的str
知道了这个操作,以后很多操作就会非常简单。
比如

获取当前时间戳:

str2num(char(py.int(py.time.time())))

直接用py库来调用即可,最后再使用matlab函数str2num,char处理成number类型。

调用自定义.py脚本函数

上面的方法倒是可以解决一部分难题,但是遇到方括号[]、百分号%操作符这些直接在.m文件中就不会执行了。毕竟matlab是以它的语法来解析,这样只得起调.py文件来操作。

新建test.py文件位于当前工作目录

def func():
    return '123'[::-1]

载入python脚本:


%脚本所在路径,空字符串表示当前目录 path = '' %当前目录 %path = 'a/' %当前的子目录a if count(py.sys.path,path) == 0 insert(py.sys.path,int32(0),path); end %清除脚本缓存,执行重载操作 clear classes; mod = py.importlib.import_module('test');%载入的脚本模块 %mod = py.importlib.import_module('a.test');%载入的子目录下的脚本模块 py.importlib.reload(mod);

调用py.test.func即可得到切片结果321,注意为py.str类型。
子目录形同:py.子目录.文件名.函数名

当修改py文件之后再调用会发现还是之前的结果,matlab缓存了之前的python脚本,所以这里需要clear classes...这类操作。

参考:
MATLAB 调用 Python

https://www.cnblogs.com/zknublx/p/6212590.html

https://blog.csdn.net/jnulzl/article/details/51170859

https://zhuanlan.zhihu.com/p/42598340

https://blog.csdn.net/x5675602/article/details/52134981

http://www.1cae.com/a/MatLab/52/python-matlab-8943.htm

matlab循环遍历struct结构体

作者:matrix 发布时间:2019年6月27日星期四 分类:零零星星

图片4911-matlab循环遍历struct结构体
matlab网络请求操作完成之后需要对返回数据读取,操作时候出现的问题就是无法循环struct数据。
因为接口一般以json数据格式返回,matlab会把Object结构处理为struct数据而无法循环读取。很多字段的时候我可不希望看到手写矩阵声明。
取struct长度的sizelength都无法正常返回其元素个数,听说它不是向量。

办法

fieldnames函数获取struct的字段field数据(返回为cell元胞数组)
之后用structName.(expression)这种操作获取动态的struct数组数据。比如struct.a等同于动态操作的struct.('a')
现在才知道文档上有,我TM竟然随便点括号猜出来的~

%声明方式1
%s = struct('a',11,'b',222)

%声明方式2
s=struct
s.a = 11
s.b = 222

% https://ww2.mathworks.cn/help/matlab/ref/struct.html

fileds = fieldnames(s);

for i=1:length(fileds)
    k = fileds(i);
    key = k{1};
    value = s.(key);

    disp(key)
    disp(value)
    disp('---')
end

% s.('a') %动态结构体引用

升级操作:自动生成对应变量

按照Struct字段自动生成对应的变量名和值

s = struct('a',11,'b',222)

fileds = fieldnames(s);

for i=1:length(fileds)
    k = fileds(i);
    key = k{1};
    value = s.(key);
    eval(['variable_',num2str(key) ' = ' num2str(value)])
end

说明:
使用eval函数动态创建variable_%s的变量。
本来在mathworks上看到有人发布过Structure fields to variables方法来自动处理struct,但是没有正版授权码 所以无法下载使用。

参考:
https://ww2.mathworks.cn/help/matlab/learn_matlab/types-of-arrays.html
https://ww2.mathworks.cn/help/matlab/ref/struct.html
https://www.ilovematlab.cn/thread-317868-1-1.html

https://ww2.mathworks.cn/matlabcentral/fileexchange/26216-structure-fields-to-variables

PEACE~

Matlab网络请求操作

作者:matrix 发布时间:2019年6月22日星期六 分类:零零星星

matlab这个学术界的编程语言我是几个月前听说,有些基本操作是真的麻烦,当然在其他方面Matlab是相当🐂🍺

使用Matlab进行GET/POST请求调用接口,提交参数。

之前苦于没有将get请求的query参数进行变量提取,好在www.mathworks.com找到有文档说明

GET请求操作函数封装

get网络请求封装成函数get_request

%GET网络请求
function [result]=get_request(uri,query)

    import matlab.net.* %导入Matlab网络请求库
    import matlab.net.http.*

    uri = URI(uri);%请求地址;
    uri.Query = matlab.net.QueryParameter(query);%get  附加请求参数 

    r = RequestMessage;
    r.Method = 'GET';%使用GET请求类型

    response = send(r,uri);%发送请求
    status = response.StatusCode%获取服务器响应的状态码
    if (status==200) %一般成功响应的状态码为200 表示ok 即成功
        content = response.Body.Data; %获取服务器响应的内容
        result = content;
    else
        disp('请求失败')
    end

说明:

参数1 uri: 请求url, 如:http://hhtjim.com
参数2 query: get请求参数 传入struct类型数据
还有就是接口返回json数据(response响应头有指定type json),matlab会自动解析json数据,最后用response.Body.Data调用就好,不方便查看的那就debug。

如果要手动处理json字符串的话使用jsonencode, jsondecode进行编解操作。

调用举例:
请求:http://hhtjim.com?arg=123

get_request('http://hhtjim.com',struct('arg', '123'))

或者

query.arg = '123'
get_request('http://hhtjim.com',query)

上面两种方式的调用都可以完成操作。matlab内部会自己封装拼接为http://hhtjim.com?arg=123进行请求。

如果想要更简单的ge请求可以使用webread进行操作。

POST请求

这里测试的POST的请求更为复杂,会添加自定义请求头,post body表单内容,cookie的涉及。所以没有封装成统一调用的函数,需要的自行修改咯~

import matlab.net.* %倒入Matlab网络请求库
import matlab.net.http.*

uri = URI('http://localhost:8080/testOrder/double_param/');%请求地址

%添加请求参数
qStruct.K=1;
qStruct.d2=2;
qStruct.d1=3;
qStruct.L=4;
qStruct.order_switch=1;%1开 0关
qStruct.order_size=2;
qStruct.diff_earnings=1.00009;



r = RequestMessage;
r.Method = 'POST'%使用POST请求类型
csrf = 'YYC0e8GICcEroZGDuL8THJ4ZQdwQpDqNtkBsfnaBP0XpH3rqYVNXADJGpWdo53o0'%Djabgo框架表单中防止跨站请求的参数,其实这是服务器生成的伪随机字符
qStruct.csrfmiddlewaretoken=csrf;
r.Body = matlab.net.QueryParameter(qStruct)%放入请求参数

%添加请求头
r = addFields(r,'Content-Type','application/x-www-form-urlencoded');
r = addFields(r,'Cookie',sprintf('csrftoken=%s',csrf));


response = send(r,uri);%发送请求
status = response.StatusCode%获取服务器响应的状态码
if (status==200) %一般成功响应的状态码为200 表示ok 即成功
    content = response.Body.Data %获取服务器响应的内容
    disp('请求成功:')
    disp(content)
else
    disp('请求失败')
end

%参考:
%https://ww2.mathworks.cn/help/matlab/http-interface.html
%https://ww2.mathworks.cn/help/matlab/ref/matlab.net.http.requestmessage.send.html#bu199af-6
%https://www.mathworks.com/help/matlab/ref/matlab.net.http.message.addfields.html
%https://ww2.mathworks.cn/help/matlab/ref/matlab.net.queryparameter-class.html

最后我真想说术业有专攻,用matlab进行网络请求是的自讨苦吃。

参考:

https://ww2.mathworks.cn/help/matlab/ref/matlab.net.uri-class.html#bvflp65-2

https://ww2.mathworks.cn/help/matlab/http-interface.html
https://ww2.mathworks.cn/help/matlab/ref/matlab.net.http.requestmessage.send.html#bu199af-6
https://www.mathworks.com/help/matlab/ref/matlab.net.http.message.addfields.html
https://ww2.mathworks.cn/help/matlab/ref/matlab.net.queryparameter-class.html