<font color="#000000"><br></font><br><div class="gmail_quote">On Thu, Jan 31, 2013 at 10:28 AM, Chris Angelico <span dir="ltr"><<a href="mailto:rosuav@gmail.com" target="_blank">rosuav@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im"><br>
>> Well, that surely isn't going to work, because it always decorates the<br>
>> same function, the global "fcn".<br>
><br>
><br>
> I don't think this is right.  fcn is a passed function (at least if it acts<br>
> as a decorator) that is declared locally in the _protector_decorator scope.<br>
> Since newfcn is bound in the same scope and fcn is not defined inside<br>
> newfcn, I'm pretty sure that newfcn will just grab the fcn passed into the<br>
> decorator.<br>
<br>
</div>Yet it adds a level of indirection that achieves nothing. Why not simply:<br>
def _protector_decorator(fcn):<br>
  return fcn<br>
<br>
? I'm not understanding the purpose here.<br></blockquote><div><br></div><div>Bad example.  A better (longer) one that is closer to my true use-case:</div><div><br></div><div><div><br></div><div>from somewhere.exceptions import MyTypeError</div>
<div>from somewhere.different import AuthorClass, RemoteAuthorClass</div><div>from urllib2 import HTTPError</div><div><br></div><div>class A(object):</div><div>   </div><div>   authorclass = AuthorClass</div><div><br></div>
<div>   def __init__(self, obj_list):</div><div>      """</div><div>      Instantiate a list of obj_list objects that may have an "author"</div><div>      attribute</div><div>      """</div>
<div>      self.things = []</div><div>      for o in obj_list:</div><div>         if not isinstance(o, self.authorclass):</div><div>            raise MyTypeError('Bad type given to constructor')</div><div>         self.things.append(o)</div>
<div><br></div><div>   def _protector(fcn):</div><div>      def newfcn(self, *args, **kwargs):</div><div>         try:</div><div>            return fcn(self, *args, **kwargs) # returns a string</div><div>         except AttributeError:</div>
<div>            return 'Attribute not available.'</div><div>         except IndexError:</div><div>            return 'Not that many AuthorClasses loaded'</div><div><br></div><div>      return newfcn</div>
<div><br></div><div>   @_protector</div><div>   def author(self, idx):</div><div>      return self.things[idx].author</div><div><br></div><div>   @_protector</div><div>   def description(self, idx):</div><div>      return self.things[idx].description</div>
<div><br></div><div>   @_protector</div><div>   def hobbies(self, idx):</div><div>      return self.things[idx].hobbies</div><div><br></div><div>class B(A):</div><div>   </div><div>   authorclass = RemoteAuthorClass</div>
<div>   </div><div>   def _protector(fcn):</div><div>      def newfcn(self, *args, **kwargs):</div><div>         try:</div><div>            return fcn(self, *args, **kwargs)</div><div>         except AttributeError:</div>
<div>            return 'Attribute not available'</div><div>         except IndexError:</div><div>            return 'Not that many RemoteAuthorClasses loaded'</div><div>         except HTTPError:</div><div>
            return 'Could not connect'</div><div>      return fcn</div><div><br></div><div>Basically, while RemoteAuthorClass and AuthorClass are related (via inheritance), the RemoteAuthorClass has the potential for HTTPError's now.  I could just expand the A class decorator to catch the HTTPError, but since that should not be possible in AuthorClass, I'd rather not risk masking a bug.  I'm under no impressions that the above code will decorate A-inherited functions with the B-decorator (I know it won't), but that's the effect I'm trying to achieve...</div>
<div><br></div><div>Thanks!</div><div>Jason</div><div><br></div></div></div>-- <br>Jason M. Swails<br>Quantum Theory Project,<br>University of Florida<br>Ph.D. Candidate<br>352-392-4032