diff --git a/manual/python/index.md b/manual/python/index.md index e4671539..794389e8 100644 --- a/manual/python/index.md +++ b/manual/python/index.md @@ -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 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.