18个版本 (10个破坏性更新)
0.12.0 | 2023年7月6日 |
---|---|
0.10.0 | 2022年9月16日 |
0.8.0 | 2021年12月4日 |
0.7.1 | 2021年8月31日 |
0.3.1 | 2019年6月19日 |
#440 在 Rust模式
每月418次下载
在 3 个crate 中使用
18KB
155 行
inline-python
直接在Rust代码中嵌入Python代码。
示例
use inline_python::python;
fn main() {
let who = "world";
let n = 5;
python! {
for i in range('n):
print(i, "Hello", 'who)
print("Goodbye")
}
}
如何使用
使用 python!{..}
宏直接在Rust代码中编写Python代码。
注意: 需要 Rust nightly 工具链。功能 proc_macro_span
仍然是不稳定的,更多详情请查看 问题 #54725 - 跟踪 proc_macro::Span
检查API
使用Rust变量
要引用Rust变量,使用 'var
,如上例所示。 var
需要实现 pyo3::ToPyObject
。
重用Python上下文
可以预先创建一个 Context
对象,并使用它来运行Python代码。上下文可以被重用于多次调用,以在宏调用之间共享全局变量。
let c = Context::new();
c.run(python! {
foo = 5
});
c.run(python! {
assert foo == 5
});
作为快捷方式,可以将 python!{}
调用直接分配给类型为 Context
的变量,以创建一个新的上下文并在其中运行Python代码。
let c: Context = python! {
foo = 5
};
c.run(python! {
assert foo == 5
});
返回信息
Context
对象也可以用来将信息返回到Rust,因为你可以通过 Context::get
从上下文中检索全局Python变量。
let c: Context = python! {
foo = 5
};
assert_eq!(c.get::<i32>("foo"), 5);
语法问题
由于Rust标记器会标记Python代码,一些有效的Python代码被拒绝。有两个主要的事情要记住
-
使用双引号字符串(
""
)而不是单引号字符串(''
)。(单引号字符串仅在它们包含单个字符时才有效,因为在Rust中,
'a'
是一个字符字面量。) -
使用
//
注释而不是#
注释。(如果您使用
#
注释,Rust标记化器将尝试对您的注释进行标记化,如果您的注释未正确标记化,则会报错。)
其他不工作的小问题包括
-
字符串字面量中的某些转义码。具体来说:
\a
,\b
,\f
,\v
,\N{..}
,\123
(八进制转义码),\u
和\U
。)然而,这些都可以正常接受:
\\
,\n
,\t
,\r
,\xAB
(十六进制转义码)和\0
-
带有转义双引号的原始字符串字面量。例如:
r"...\"..."
。 -
包含无效正则字符串内容的原始字节和原始字符串字面量。以及原始字节和原始格式字符串也是如此。例如:
b"""\xFF"""
,r"""\z"""
,fr"\z"
,br"\xFF"
。 -
//
和//=
运算符不可用,因为它们开始一个注释。解决方案:您可以写
##
代替,它将被自动转换为//
。
其他所有内容都应正常工作。
依赖关系
约2.5-7.5MB
约55K SLoC