Note that there are some explanatory texts on larger screens.

plurals
  1. POUsing a decorator function that is a method in a class on other methods within the class in python
    primarykey
    data
    text
    <p>I have been trying to learn more about decorators using a tweaked version as below from: <a href="http://code.activestate.com/recipes/440499/" rel="nofollow">here</a></p> <pre><code>def case(comparision): def __assign_case(f): f.__case = comparision return f return __assign_case class switch: def __init__(self): self.__case_map = {} def set_case(key,f): self.__case_map[key] = f a = [getattr(self,e) for e in dir(self) if getattr(self,e) is not None and hasattr(getattr(self,e),'__case')] for f in a: cases = getattr(f,'__case') if isinstance(cases,tuple) or isinstance(cases,list): for c in cases: set_case(c,f) else: set_case(cases,f) print(self.__case_map) def match(self,value): try: self.__case_map[value] except KeyError: return self.__case_map['_default'] return self.__case_map[value] class b(switch): @case((1,3)) def event_one(self): print('Event handler for 1,3 in b') @case(2) def event_two(self): print('Event handler for 2 in b') @case('_default') def default(self): print('No match was found, using default case') a = b() a.match(1)() a.match(2)() a.match(5)() </code></pre> <p>With results with run of:</p> <pre><code>$ ./switch_decor.py {1: &lt;bound method b.event_one of &lt;__main__.b object at 0x7f03374849d0&gt;&gt;, '_default': &lt;bound method b.default of &lt;__main__.b object at 0x7f03374849d0&gt;&gt;, 3: &lt;bound method b.event_one of &lt;__main__.b object at 0x7f03374849d0&gt;&gt;, 2: &lt;bound method b.event_two of &lt;__main__.b object at 0x7f03374849d0&gt;&gt;} Event handler for 1,3 in b Event handler for 2 in b No match was found, using default case </code></pre> <p>Notice the filled dictionary</p> <p>I like to keep my code contained, so was trying to move the <code>case</code> function into the <code>switch</code> class like so:</p> <pre><code>class switch: def __init__(self): self.__case_map = {} def set_case(key,f): self.__case_map[key] = f a = [getattr(self,e) for e in dir(self) if getattr(self,e) is not None and hasattr(getattr(self,e),'__case')] for f in a: cases = getattr(f,'__case') if isinstance(cases,tuple) or isinstance(cases,list): for c in cases: set_case(c,f) else: set_case(cases,f) print(self.__case_map) def match(self,value): try: self.__case_map[value] except KeyError: return self.__case_map['_default'] return self.__case_map[value] @staticmethod def case(comparision): def __assign_case(f): f.__case = comparision return f return __assign_case class b(switch): @switch.case((1,3)) def event_one(self): print('Event handler for 1,3 in b') @switch.case(2) def event_two(self): print('Event handler for 2 in b') @switch.case('_default') def default(self): print('No match was found, using default case') a = b() a.match(1)() a.match(2)() a.match(5)() </code></pre> <p>But I end up getting an empty <code>self.__case_map</code> dictionary resulting in this error:</p> <pre><code>$ ./switch_decor_contained.py {} Traceback (most recent call last): File "./switch_decor_contained.py", line 23, in match self.__case_map[value] KeyError: 1 During handling of the above exception, another exception occurred: Traceback (most recent call last): File "./switch_decor_contained.py", line 50, in &lt;module&gt; a.match(1)() File "./switch_decor_contained.py", line 25, in match return self.__case_map['_default'] KeyError: '_default' </code></pre> <p>Notice the blank dictionary at the beginning. It fails at</p> <pre><code>a.match(1) </code></pre> <p>before that return function is invoked with the second <code>()</code> which is a function of the dictionary being blank tripping the exception but there is no <code>_default</code> key to the function value to return.</p> <p>On the first set of code above, running this in a console gives:</p> <pre><code>&gt;&gt;&gt; hasattr(a.event_one, "__case") True </code></pre> <p>But on the second set of code above, running </p> <pre><code>&gt;&gt;&gt; hasattr(a.event_one, "__case") False </code></pre> <p>Despite the fact that <code>@switch.case</code> is being run as tests on that showed. There is some untoward side effect from invoking it within a class. What is the side effect?</p> <p>How can I move the <code>case</code> function into the <code>switch</code> class and use it as a method successfully to decorate the functions in class <code>b</code>?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload