8次发布

0.5.7 2023年7月6日
0.5.6 2023年6月26日
0.5.5 2022年9月16日
0.5.4 2021年12月4日
0.5.0 2020年6月3日

#147 in 过程宏

Download history 6/week @ 2024-03-08 2/week @ 2024-03-15 19/week @ 2024-03-29 4/week @ 2024-04-05

每月 62 次下载

BSD-2-Clause

5KB

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上下文

可以在运行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:

在编译时执行Python代码以生成Rust代码。

示例

use ct_python::ct_python;

static SIN_2: f64 = ct_python! {
    from math import sin
    print(sin(2))
};

ct_python! {
    print("type num = f64;")
}

fn main() {
    assert_eq!(num::sin(2.0), SIN_2);
}

如何使用

使用ct_python!{..}宏从嵌入的Python脚本中生成Rust代码。脚本的输出(print()和通过sys.stdout的其他内容)被捕获,并将被解析为Rust代码。

Python 错误

Python代码中的任何语法错误或运行时异常都将由Rust编译器报告为编译器错误。

语法问题

由于Rust分词器会解析Python代码,一些有效的Python代码可能会被拒绝。有关详细信息,请参阅inline-python》文档

依赖项

~2.5–8MB
~55K SLoC