<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