質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

708閲覧

PyO3で作成したClassに別のClassをCloneせず入れたい

namuyan

総合スコア76

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/03/30 06:21

編集2020/03/30 10:30

クラスに別のクラスを格納したい

やりたい事を下記のようにコードにしました(動きません。
OuterクラスにInnerを格納します。このInnerは別のオブジェクトとしてCloneされず、参照数がインクリメントされ同一のオブジェクトが入るようにしたいです。Cloneされると別のオブジェクトとなり一方に行った変更が反映されません。

rust

1#[pyclass] 2stract Inner { 3 a: u32 4} 5 6#[pyclass] 7stract Outer { 8 inner: Inner 9} 10 11#[pymethods] 12impl Outer { 13 #[new] 14 fn new(inner: &Inner) -> PyResut<Self> { 15 let inner = inner.deref(); 16 Ok(Outer{inner}) 17 } 18 19 fn get(&self) -> u32 { 20 self.inner.a 21 } 22}

一方で下記の様に書き換えました(動きます。
オブジェクトがCloneされず同一のままですが特定のClassではないので格納するだけになり内部で作業する事ができません。

rust

1#[pyclass] 2stract Inner { 3 a: u32 4} 5 6#[pyclass] 7stract Outer { 8 inner: PyObject 9} 10 11#[pymethods] 12impl Outer { 13 #[new] 14 fn new(inner: PyObject) -> PyResut<Self> { 15 Ok(Outer{inner}) 16 } 17 18 fn get(&self) -> u32 { 19 self.???.a 20 } 21}

参考になりそうなもの

PyO3のドキュメントを読んでいますがどうすればいいのかわかりません。
何かわかる方は回答の方をよろしくお願いします。

追記 2020/3/30 19時

前回の質問 を見直してこねくり回していたら同じオブジェクトを格納できたようです。しかし今度は格納したオブジェクトの操作方法がわかりません。extractしてPyRefPyRefMutでラップした型を借りると思うのですが。

rust

1#[pyclass] 2stract Inner { 3 a: u32 4} 5 6#[pyclass] 7stract Outer { 8 inner: Py<Inner> 9} 10 11#[pymethods] 12impl Outer { 13 #[new] 14 fn new(inner: &PyCell<Inner>) -> PyResut<Self> { 15 let inner = inner.into(); 16 Ok(Outer{inner}) 17 } 18 19 20 fn obj(&self, py: Python) -> PyObject { 21 self.inner.to_object(py) 22 } 23 24 fn get(&self) -> u32 { 25 // not work 26 self.inner.a 27 } 28}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

https://docs.rs/pyo3/0.9.1/pyo3/prelude/trait.AsPyRef.html

AsPyRefで&PyCell<Inner>を持ってきてそこからtry_borrowborrowPyRefというのが一応意図したインターフェースです。
ちょっとこの辺はtrait実装が衝突する関係であまり便利ではないですが。

投稿2020/03/31 03:48

kngwyu

総合スコア48

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

自己解決

追記を書いてからすぐにできました。
余計な操作が入っているように見えますが、一応動きます。

rust

1#[pyclass] 2struct Inner { 3 a: u32 4} 5 6#[pyclass] 7struct Outer { 8 inner: Py<Inner> 9} 10 11#[pymethods] 12impl Outer { 13 #[new] 14 fn new(inner: &PyCell<Inner>) -> PyResut<Self> { 15 let inner = inner.into(); 16 Ok(Outer{inner}) 17 } 18 19 20 fn obj(&self, py: Python) -> PyObject { 21 self.inner.to_object(py) 22 } 23 24 //fn get(&self, py: Python) -> u32 { 25 // let obj = self.inner.to_object(py); 26 // let rc: PyRef<Inner> = obj.extract(py).unwrap(); 27 // rc.a 28 //} 29 30 fn get(&self, py: Python) -> u32 { 31 let cell: &PyCell<Inner> = self.inner.as_ref(py); 32 let rc: PyRef<Inner> = cell.borrow(); 33 rc.a 34 } 35}

&PyCell<Inner>Py<Inner>PyObjectPyRef<Inner>orPyRefMut<Inner>で操作?何かもっと良い方法があれば回答の方をよろしくお願いします。

追記 4/1

メンテナーによる別回答を元に想定された使い方の具体例を載せました。

投稿2020/03/30 11:30

編集2020/04/01 04:25
namuyan

総合スコア76

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問