16 个版本 (9 个重大更新)
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日 |
#1855 in 过程宏
每月457次下载
用于 5 个 crate (直接使用 2 个)
14KB
309 代码行数(不含注释)
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"
。) -
操作符
//
和//=
无法使用,因为它们会开始一个注释。解决方案:您可以写
##
代替,它将被自动转换为//
。
其他所有事情都应该运行良好。
lib.rs
:
为 inline-python
和 ct-python
提供辅助的 crate。
依赖项
~2.5–8MB
~55K SLoC