『科技排头』在Rust代码中编写Python是种怎样的体验?( 五 )


开始时多余的换行符不是问题(空行在Python中无效) 。 它甚至具有很好的副作用:当Python报告错误时 , 它报告的行号将与.rs文件中的行号匹配 。
但是 , 这8个空格是个问题 。 尽管我们内部的Python代码python!{..}相对于Rust代码是适当缩进的 , 但我们提取的Python代码应以“零”缩进级别开始 。 否则 , Python将发生无效缩进的错误 。
让我们从所有列号中减去第一个标记的列号:
start_col:None,//<snip>start_col:Option<usize>,//<snip>letstart_col=*self.start_col.get_or_insert(loc.column);letcol=loc.column.checked_sub(start_col).expect(''Invalidindentation.'');whileself.col<col{self.source.push('');self.col+=1;}//<snip>$cargorCompilingpython-macrov0.1.0Compilingscratchpadv0.1.0print(''...World!'')print(''Bye.'')error:procmacropanicked结果太棒了!
现在 , 我们只需要把这个字符串转换为字符串文字标记并将其放在run_python;周围即可:
TokenStream::from_iter(vec![TokenTree::from(Ident::new(''run_python'',Span::call_site())),TokenTree::Group(Group::new(Delimiter::Parenthesis,TokenStream::from(TokenTree::from(Literal::string(&s.source))),)),TokenTree::from(Punct::new(';',Spacing::Alone)),])太糟糕了 , 直接使用TokenTree太困难了 , 尤其是从头开始制作trees和streams 。
如果只有一种方法可以编写我们要生成的Rust代码 , 那就只能是quote类库的quote!宏:
letsource=s.source;quote!(run_python(#source);).into现在使用我们的原始run_python函数对其进行测试:
#![feature(proc_macro_hygiene)]usepython_macro::python;fnrun_python(code:&str){letpy=pyo3::Python::acquire_gil;ifletErr(e)=py.python.run(code,None,None){e.print(py.python);}}fnmain{println!(''Hello...'');python!{print(''...World!'')print(''Bye.'')}}$cargorCompilingscratchpadv0.1.0Finisheddev[unoptimized+debuginfo]target(s)in0.31sRunning`target/debug/scratchpad`Hello......World!Bye.终于成功了!
『科技排头』在Rust代码中编写Python是种怎样的体验?
文章图片
封装成类库
现在我们把它变成一个可重用的库:
删除fnmain ,
重命名main.rs为lib.rs ,
给类库起个好名字 , 例如inline-python ,
公开run_python ,
更改quote!中的run_python调用改为::inline_python::run_python , 同时添加pubpython_macro::python;从python!这个类库中重新导出宏 。
『科技排头』在Rust代码中编写Python是种怎样的体验?
文章图片
下一步计划
可能还有很多内容需要改进 , 还有很多错误需要发现 , 但是至少我们现在可以在Rust代码行之间运行Python片段了 。
目前最大的问题是 , 这还不是很有用 , 因为没有数据可以(轻松)越过Rust-Python的边界 。
在第2部分中 , 我们将研究如何使Rust变量用于Python代码 。
更新:在等待第2部分的同时 , 还有第1A部分 , 只是它没有改进我们的python!{}宏 , 但涉及了人们向我询问的一些细节 。 具体来说 , 它涉及:
为什么要像这样在Rust内部使用Python ,
语法问题 , 例如使用Python的单引号字符串
使用Span::source_text的选项 , 当我第一次编写这段代码时 , 它其实还不存在 。
原文链接:https://blog.m-ou.se/writing-python-inside-rust-1/
『科技排头』在Rust代码中编写Python是种怎样的体验?
文章图片
360金融首席科学家张家兴:别指望AILab做成中台我们想研发一个机器学习框架 , 6个月后失败了