[Tutor] decorators in a class

Peter Otten __peter__ at web.de
Tue Jun 13 03:09:12 EDT 2017


anish singh wrote:

> Trying to use decorators in my class. I am calling
> build_tree from the main function and i want to increment
> the arguments by a constant factor by using decorators.
> However as build_tree is a recursive function, I don't want
> to call it recursively with increased constant factor always.
> 
> Probably decorators are not the ideal way for this but still
> how to go about it using decorators.
> 
> Simple solution would be to just pass the parameters after
> incrementing with constant values in the main function.
> However, I want the caller of build_tree to not know that
> internally we increment the indexes in the class and work
> on that.
> I can also call a intermediate function and then call build_tree
> but then would that be the right way?

Your decorator is so specific that it will probably be used only once, and 
it interferes with your intention to call both the decorated and the 
undecorated version of the method.

These are strong indications that decorators are not the right tool in this 
case. Instead I suggest that you use two methods:

class SegmentTree:
    def build_tree(self, left, right, root):
        n = self.n
        return self._build_tree(left + n, right + n, root)

    def _build_tree(self, left, right, root):
        # recursive calls invoke _build_tree, not build_tree
        ...

If you insist you can probably write that

class SegmentTree:
    def _build_tree(self, left, right, root):
        # recursive calls invoke _build_tree, not build_tree
        ...

    build_tree = p_decorate(_build_tree)

> def pow_of_2(n):
>     n -= 1
>     n |= n >> 1
>     n |= n >> 2
>     n |= n >> 4
>     n |= n >> 8
>     n |= n >> 16
>     n += 1
>     return n
> 
> def p_decorate(func):
>     def func_wrapper(self, left, right, root):
>         return func(self, left+self.n, right+self.n, root)
>     return func_wrapper
> 
> class segment_tree(object):
>     def __init__(self, data):
>         self.n = pow_of_2(len(data))
>         self.tree = [0]*self.n + data + [0]*(self.n - len(data))
> 
>     @p_decorate
>     def build_tree(self, left, right, root):
>         if left == right:
>             return self.tree[left]
>         #below build_tree should not use decorated function,
>         #how to achieve that?
>         s = self.build_tree(left, (left+right)/2, 2*root) +
>                   self.build_tree(1+(left+right)/2, right, 2*root+1)
>         self.tree[root] = s
> 
>     def __repr__(self):
>         return " ".join(str(i) for i in self.tree)
> 
> data = [1, 2, 3, 4]
> sg = segment_tree(data)
> sg.build_tree(0, 7, 1)
> print(sg)
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor




More information about the Tutor mailing list