Constructors
In the previous section (and its exercise) we relied on a #[pyfunction]
as the constructor for the #[pyclass]
we defined. Without new_wallet
, we wouldn't have been able to create new Wallet
instances from Python.
Let's now explore how to define a constructor directly within the #[pyclass]
itself.
Defining a constructor
You can add a constructor to your #[pyclass]
using the #[new]
attribute on a method. Here's an example:
#![allow(unused)] fn main() { use pyo3::prelude::*; #[pyclass] struct Wallet { #[pyo3(get, set)] balance: i32, } #[pymethods] impl Wallet { #[new] fn new(balance: i32) -> Self { Wallet { balance } } } }
A Rust method annotated with #[new]
is equivalent to the __new__
method in Python. At the moment there is no way to
define the __init__
method in Rust.
The impl
block containing the constructor must also be annotated with the #[pymethods]
attribute for #[new]
to work as expected.
Signature
Everything we learned about arguments in the context of #[pyfunction]
s applies to constructors as well.
In terms of output type, you can return Self
if the constructor is infallible, or PyResult<Self>
if it can fail.
Exercise
The exercise for this section is located in 02_classes/01_constructors