Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

expand example using @pythonize #1049

Merged
merged 2 commits into from
Nov 25, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions manual/python/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -408,14 +408,30 @@ The loading of C++ libraries can even be automated using the `__init__.py` of th

PyROOT allows to inject new behaviour in C++ user classes that are used from Python - this is known as "pythonizing" those C++ classes. The aim here is to make C++ classes more "pythonic" or easier to use from Python, for example by making a C++ class iterable in Python or by defining how its objects should be represented as strings in Python.

Pythonizations for C++ classes can be registered by providing a function, the "pythonizor", which is decorated with the `@pythonization` decorator. The decorator specifies to which class or classes the pythonization should be applied, and the pythonizor function contains the code that performs the pythonization. For instance, the following code snippet registers a pythonization for class `C` that adds a new attribute to that class:
Pythonizations for C++ classes can be registered by providing a function, the "pythonizor", which is decorated with the `@pythonization` decorator. The decorator specifies to which class or classes the pythonization should be applied, and the pythonizor function contains the code that performs the pythonization. For instance, the following code snippet registers a pythonization for class `MyContainer` that adds `len` Python method and binds it to an appropriate C++ method.

```python
import ROOT
ROOT.gInterpreter.Declare('''
class MyContainer {
public:
size_t GetSize() const { return m_vec.size(); }
private:
std::vector<double> m_vec;
};
''')

container = ROOT.MyContainer()
len(container) # TypeError: object of type 'MyContainer' has no len()

# pythonize MyClass by adding `__len__` and binding it to `GetSize`
from ROOT import pythonization
@pythonization("MyContainer")
def pythonize_two_classes(klass):
klass.__len__ = klass.GetSize

@pythonization("C")
def pythonizor_for_C(klass):
klass.new_attr = 'New attribute' # injects a new attribute in the class
container = ROOT.MyContainer()
len(container) # 0
```

The very same mechanism is used internally in ROOT to pythonize ROOT classes, and it can be applied to user classes too since ROOT v6.26.
Expand Down
Loading