Skip to content

Redesign Python relationship into wrapper #180

@henryiii

Description

@henryiii

This could be a very large change, so I'd like to see what other think about it. This is the possible idea, proposed by Hans some time ago:

The "histogram" class would become a pure python class, with a _hist private member that holds the C++ histogram object. All calls would basically forward to the underlying _hist methods. For simplicity below, I'll call the Python histogram class "Histogram" to separate it from histogram - it does not need to be called this in the design. Design highlights:

  • Caching axes is trivially done in __init__
  • The cpp histogram class can be very close to the cpp design (and should be, to reduce cognitive load)
  • The Histogram class can have a parent BaseHistogram class (ignore my naming for now), that does not support addition and such but still has axes, that can be used as the output of .density()
  • Either the cpp histograms or a new subclass can be used to provide a highly Boost.Histogram C++ compatible syntax in boost_histogram.cpp. Without this, we will probably need to inject and remove methods to provide a compat mode.
  • The current trickery designed to make the multiple histogram classes isinstance as one goes away. Same thing for axis.* (which also get this treatment). We don't have to do the method injection loops either.
  • Docstrings can be written in Python.

Downsides:

  • All calls wrapped - tight loops might be a bit slower.
  • Adds another level of indirection, another level of design complexity - might be especially irritating when building a new library on top of this as a back end, like hist/physt/etc. Makes me think of Cython...
  • All calls creating a histogram (like slice indexing) would need to also wrap the output to turn it back into a self.__class__.
  • Things like buffer view have to be setup again in Histogram.
  • Signatures need to be crafted in Python, since all calls are redirected. But, we might be doing this anyway for nicer Python 3 signatures. Python 2 might get sub-standard *args, **kwargs signatures everywhere, but I'm not that interested in making Python 2 interactive work beautiful.

Example:

class BaseHistogram(object):
    def __init__(self, ...):
        self._hist = make_histogram(...)
        self.axes = AxesTuple(... self._hist ...)

    def __getitem__ ...
class Histogram(BaseHistogram):
    def __add__ ...

What do you think? Is the extra flexibility and simpler Python structures worth the extra complexity? This would help with #174 and #155.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions