decorators only when __debug__ == True

MRAB python at mrabarnett.plus.com
Tue Mar 30 17:41:31 EDT 2010


LX wrote:
> On Mar 29, 6:34 pm, MRAB <pyt... at mrabarnett.plus.com> wrote:
>> LX wrote:
>>> Hi all, I have a question about decorators. I would like to use them
>>> for argument checking, and pre/post conditions. However, I don't want
>>> the additional overhead when I run in non-debug mode. I could do
>>> something like this, using a simple trace example.
>>> @decorator
>>> def pass_decorator(f, *args, **kw): # what about the slow-down that
>>> incurs when using pass_decorator?
>>>     return f(*args, **kw)
>>> @decorator
>>> def trace_decorator(f, *args, **kw):
>>>     print "calling %s with args %s, %s" % (f.func_name, args, kw)
>>>     return f(*args, **kw)
>>> trace_enable_flag = False #__debug__
>>> trace = trace_decorator if trace_enable_flag else pass_decorator
>>> Trouble is, there is still an additional encapsulating function call.
>>> Is there any way to eliminate the extra function call altogether?
>>> Thanks in advance!
>> I think you have misunderstood certain details about decorators.
>>
>> This code with a decorator:
>>
>>      @decorator
>>      def hello():
>>          print "hello world"
>>
>> basically does this:
>>
>>      def hello():
>>          print "hello world"
>>      hello = decorator(hello)
>>
>> so your non-decorator just needs to return the function it was passed:
>>
>>      def pass_decorator(func):
>>          return func
>>
>> and your trace decorator would be something like this:
>>
>>      def trace_decorator(func):
>>          def show(*args, **kwargs):
>>              print "calling %s with args %s, %s" % (func.func_name,
>> args, kwargs)
>>              result = func(*args, **kwargs)
>>              print "returning %s from %s" % (result, func.func_name)
>>              return result
>>          return show
> 
> Sure, but during runtime, pass_decorator will still be called, even
> though it doesn't do anything. I am wondering if I can disable this
> additional function call at non-debug runtime. In other words, I want
> the calling stack to contain no decorator at all, not even
> pass_decorator.
> 
> I should mention that, in my code, the symbol "decorator" is imported
> from Michele Simionato's decorator.py file.

pass_decorator will be called when the decorated function is _defined_,
but not when the decorated function is _called_.



More information about the Python-list mailing list