Appelez Rust de Python pour accélérer! Tutoriel PyO3: partie des classes d'emballage ➁

Aperçu

  1. Il n'est pas préférable en termes de vitesse d'écrire l'algorithme en Pyhton ~
  2. Très bien, recherchez quelque chose d'écrit autour de C, C ++ et appelez-le depuis Python pour l'accélérer.
  3. Je ne trouve pas de bonne bibliothèque,
  4. Oh, s'il a été écrit dans une langue appelée Rust
  5. Rust peut-il être appelé depuis Python? ??

Voici Appel de Rust à partir de Python pour accélérer! Tutoriel PyO3: Wrapping Classes Part ➀

Ce sera une continuation de.

Cible

Le but, Définissez une classe Rust (struct + méthode) et appelez-la depuis Python C'était, La dernière fois, j'ai expliqué comment appeler une classe écrite en Rust depuis Python.

Le constructeur de classe et la propriété getter, setter peuvent également être appelés depuis Python via PyO3.

Cette fois, je vais ajouter quelques méthodes de classe et expliquer comment convertir du type Rust en Python via PyO3.

Voir ** le dépôt git de PyO3 ** (ici),

J'expliquerai comment passer l'objet Rust du côté Python avec PyO3.

Etc.

procédure

Utilisez le projet créé par cargo new --lib example jusqu'à la dernière fois. Bien sûr, il n'y a pas de problème même si vous en créez un nouveau.

Pour récapituler, la dernière fois, j'ai rendu possible d'appeler le getter et setter du constructeur de classe et de la propriété num de Python via PyO3. Voici le code que j'ai complété la dernière fois.


//lib.rs
use pyo3::prelude::*;
use pyo3::{wrap_pyfunction};


// ======================RUST CLASS TO PYTHON ======================================
/// Class for demonstration
// this class, MyClass can be called from python
#[pyclass(module = "my_class")]
struct MyClass {
   num: i32,
   debug: bool,
}

#[pymethods]
impl MyClass{
    #[new]
    fn new(num:i32, debug:bool) -> Self{
        MyClass{
            num: num,
            debug: debug
        }
    }

    #[getter]
    fn get_num(&self) -> PyResult<i32>{
        Ok(self.num)
    }

    #[setter]
    fn set_num(&mut self, num: i32) -> PyResult<()>{
        self.num = num;
        Ok(())
    }
}


// =================CREATING MODULE FOR PYTHON=========================
/// This module is a python module implemented in Rust.
#[pymodule]
fn test_library(py: Python, m: &PyModule) -> PyResult<()> {
    m.add_wrapped(wrap_pyfunction!(get_prime_numbers))?;
    m.add_class::<MyClass>()?;

    Ok(())
}

Cette fois, nous ajouterons 6 fonctions à cette MyClass. Immédiatement, voici le code.


//lib.rs

use pyo3::types::PyType;
use pyo3::types::PyInt;
use pyo3::types::PyList;
use pyo3::types::PyTuple;
use pyo3::types::PyDateTime;
use std::collections::HashMap;

#[pymethods]
impl MyClass{

    fn test1(&self) -> PyResult<bool>{
        if self.num > 3{
            Ok(true)
        }else{
            Ok(false)
        }
    }

    fn test2(&self) -> PyResult<String>{
        if self.debug == true{
            let result: &str = "your debug is True";
            Ok(result.to_string())
        }else{
            let result: &str = "your debug is False";
            Ok(result.to_string())
        }
    }

    fn test3<'py>(&self, py: Python<'py>) -> PyResult<&'py PyList>{
        let mut vec = vec![1,2,3];
        let result = PyList::new(py, &vec);
        Ok(result)
    }

    fn test4(&self, py: Python) -> PyResult<PyObject>{
        let mut map = HashMap::new();
        map.insert("key1", 1);
        map.insert("key2", 2);
        map.insert("key3", 3);
        assert_eq!(map["key1"], 1);
        assert_eq!(map["key2"], 2);
        assert_eq!(map["key3"], 3);
        Ok(map.to_object(py))

    }

    fn test5(&self) -> PyResult<f64>{
        let result:f64 = 1.23;
        Ok(result)
    }

    fn test6<'py>(&self, py: Python<'py>, dt: &PyDateTime) -> PyResult<&'py PyTuple>{
        let mut vec = vec![3,4,5];
        let result = PyTuple::new(py, &vec);
        Ok(result)

    }
}

fn test1 Passage de Rust's bool à Python's bool via PyO3.

fn test2 Passer Rust's String à Python's str via PyO3.

fn test3 Passer Rust's Vec à Python's List via PyO3. Je ne comprends pas comment écrire ça. ..

fn test4 Passer Rust's Hashmap à Python's Dict via PyO3.

fn test5 Passer Rust's f64 à Python's float via PyO3.

fn test6 Passer Rust's Vec au tuple de Python via PyO3. À ce stade, «Python Datetime» est reçu comme argument de la fonction. Je ne comprends pas comment écrire ça. ..

Lancer le test

En ce qui concerne test3 et test6, je ne comprends pas comment écrire honnêtement, mais je vais exécuter le test. En préparant Cargo.toml et setup.py comme précédemment,

python setup.py install

Vous pouvez construire avec.

Préparez ensuite test.py comme suit et lancez le test.

test.py



import test_library 


if __name__  == "__main__":

    # Testing class
    print("\ntest for class")
    num = 2
    debug = True
    test = test_library.MyClass(num=num, debug=debug)

    print(test.num) # getter test
    test.num = 4    # setter test
    print(test.num)
    result = test.test1()
    print(result)
    print(type(result))

    result = test.test2()
    print(result)
    print(type(result))

    result = test.test3()
    print(result)
    print(type(result))

    result = test.test4()
    print(result)
    print(type(result))

    result = test.test5()
    print(result)
    print(type(result))

    import datetime 
    now = datetime.datetime.now()
    result = test.test6(now)
    print(result)
    print(type(result))

Résumé

Cette fois, j'ai ajouté quelques méthodes de classe et expliqué comment convertir du type Rust en Python via PyO3. Bien que cela semble relativement plus facile à comprendre que Cython, la version de PyO3 elle-même est régulièrement mise à jour, donc la meilleure chose à faire est de développer avec la version à l'esprit (Fix). Ou vous devez suivre correctement Git et faire attention au changement du nom de l'API.

Cependant, Rust est intéressant, je vais donc continuer à étudier.

Cette fois par ici.

fin.

Recommended Posts

Appelez Rust de Python pour accélérer! Tutoriel PyO3: Partie des classes d'habillage ➀
Appelez Rust de Python pour accélérer! Tutoriel PyO3: partie des classes d'emballage ➁
Appelez Rust de Python pour accélérer! Tutoriel PyO3: Emballage d'une partie de fonction simple
Appelez Rust de Python pour accélérer! Tutoriel PyO3: Emballage d'une partie de fonction simple ➁
Aller au langage pour voir et se souvenir de la partie 8 Appeler le langage GO à partir de Python
Appelez Matlab depuis Python pour optimiser
Numba pour accélérer en Python
Comment accélérer les calculs Python
N'écrivez pas Python si vous voulez l'accélérer avec Python
[Python] Hit Keras depuis TensorFlow et TensorFlow depuis c ++ pour accélérer l'exécution.
Langage C pour voir et se souvenir de la partie 2 Appeler le langage C à partir de la chaîne Python (argument)
Langage C pour voir et se souvenir de la partie 1 Appeler le langage C depuis Python (bonjour le monde)
Langage C pour voir et se souvenir de la partie 4 Appelez le langage C depuis Python (argument) double
Langage C pour voir et se souvenir de la partie 5 Appel du langage C à partir du tableau Python (argument)
Langage C pour voir et se souvenir de la partie 3 Appelez le langage C depuis Python (argument) c = a + b
Étude de Python Hour7: Comment utiliser les classes
[Python] Faites de votre mieux pour accélérer SQL Alchemy
Un moyen simple d'appeler Java depuis Python
De la configuration du Raspberry Pi à l'installation de l'environnement Python
[Python] Comment appeler une fonction de c depuis python (édition ctypes)
Changements de Python 3.0 à Python 3.5
Appeler des fonctions du langage C depuis Python pour échanger des tableaux multidimensionnels
De la configuration de l'environnement Rust à l'exécution de Hello World
Comment appeler Python ou Julia à partir de Ruby (implémentation expérimentale)