#python #inline #macro #embed

inline-python

直接在Rust代码中嵌入Python代码

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日

#440Rust模式

Download history 116/week @ 2024-03-13 87/week @ 2024-03-20 89/week @ 2024-03-27 124/week @ 2024-04-03 58/week @ 2024-04-10 46/week @ 2024-04-17 68/week @ 2024-04-24 41/week @ 2024-05-01 68/week @ 2024-05-08 74/week @ 2024-05-15 78/week @ 2024-05-22 136/week @ 2024-05-29 117/week @ 2024-06-05 94/week @ 2024-06-12 110/week @ 2024-06-19 70/week @ 2024-06-26

每月418次下载
3 个crate 中使用

BSD-2-Clause

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