Macro python_comm::from_py[][src]

macro_rules! from_py {
    ($py : tt, dict, $obj : tt, $any1 : expr, default $default : expr) => { ... };
    ($py : tt, dict, $obj : tt, $any1 : expr, $($any2 : tt), *) => { ... };
    ($py : tt, obj, $obj : tt, $any1 : expr, default $default : expr) => { ... };
    ($py : tt, obj, $obj : tt, $any1 : expr, $($any2 : tt), *) => { ... };
    (0 $fn1 : ident, $fn2 : ident, $py : ident, $obj : ident, $field : expr,
 default $default : expr) => { ... };
    (0 $fn1 : ident, $fn2 : ident, $py : ident, $obj : ident, $field : expr,) => { ... };
    (0 $fn1 : ident, $fn2 : ident, $py : ident, $obj : ident, $field : expr,
 datetime) => { ... };
    (0 $fn1 : ident, $fn2 : ident, $py : ident, $obj : ident, $field : expr,
 Decimal) => { ... };
    (0 $fn1 : ident, $fn2 : ident, $py : ident, $obj : ident, $field : expr, $type
 : ty) => { ... };
    (1 $fn1 : ident, $fn2 : ident, $py : ident, $obj : ident, $field : expr) => { ... };
}
Expand description

从 python dict/obj 中提取指定字段

用法

use cpython::{Python, PyDict, PyObject};
use python_comm::prelude::*;
use rust_decimal_macros::dec;

let gil = Python::acquire_gil();
let py = gil.python();
let os = py.import("os").unwrap();
let pobj: PyObject = os.get(py, "environ").unwrap().extract(py).unwrap();

// 用法1:从 python obj 中提取指定字段, 其中 obj 是关键字
let pdict:PyDict = from_py!(py, obj, pobj, "_data",).unwrap();
let error:Result<PyDict, _> = from_py!(py, obj, pobj, "none",);
assert!(error.is_err());

// 用法2:从 python dict 中提取指定字段, 其中 dict 是关键字
// let path:String = from_py!(py, dict, pdict, "PATH").unwrap(); linux 下是 b'PATH' 为 key
let error:Result<String, _> = from_py!(py, dict, pdict, "none",);
assert!(error.is_err());

let locals = PyDict::new(py);
locals.set_item(py, "decimal", py.import("decimal").unwrap()).unwrap();
locals.set_item(py, "datetime", py.import("datetime").unwrap()).unwrap();
let pdict:PyDict = py
    .eval(
        r#"{"time": datetime.datetime.now(), "num": decimal.Decimal('2.5'), "text": "abc"}"#,
        None,
        Some(&locals),
    )
    .unwrap()
    .extract(py)
    .unwrap();

// 用法3:在用法 1-2 基础上指定 datetime 类型
let time = from_py!(py, dict, pdict, "time", datetime).unwrap();
assert!(time.date().year() >= 2021);

// 用法4:在用法 1-2 基础上指定 Decimal 类型
let num = from_py!(py, dict, pdict, "num", Decimal).unwrap();
assert_eq!(num, dec!(2.5));

// 用法5:在用法 1-2 基础上指定 其它 类型
let text = from_py!(py, dict, pdict, "text", String).unwrap();
assert_eq!(text, "abc");

// 用法6:在用法 1-5 基础上指定缺省值
let default = from_py!(py, dict, pdict, "none", default String::from("default")).unwrap();
assert_eq!(default, "default");

参考 https://danielkeep.github.io/tlborm/book/mbe-min-captures-and-expansion-redux.html 一旦被捕获, 则不能再当作一般文本进行 match, ident/tt 除外 stringify 是内置的, 不能被 tt 匹配, 必须用 expr