Python: Controlling Decorators
by Demolishun · 05/18/2012 (10:23 pm) · 3 comments
Python does not have a preprocessor. In C you can control compilation like this:
In Python however there is no way to do that with a preprocessor. Now Python has a really cool concept called a decorator. It will allow other code to wrap a function with a "wrapper" to achieve some kind of added functionality. It works off of the principle that every Python function is an object:
Now a decorator does this:
The way I solved this was to use the #define trick from C:
What originally drew me to this method was the __debug__ symbol Python uses. However __debug__ has to be disabled by a command line object and it also squashes asserts. Asserts can be used for other things besides conditions that might be fatal. So unless one can guarantee __debug__ is only used for asserts then it is best to use your own symbol to control your debug decorators.
So, in a way Python does have proprocessing capabilities as it does have an initial parse of the code before it is run. This initial parse can be used to define if objects are created based upon variables. Not exactly the same way as C preprocessors work, but enough to get the behavior we want.
#define __CODE_FLAG__
...
#ifdef __CODE_FLAG__
int variable;
void function(){
}
#endifThis can be really useful. In Python however there is no way to do that with a preprocessor. Now Python has a really cool concept called a decorator. It will allow other code to wrap a function with a "wrapper" to achieve some kind of added functionality. It works off of the principle that every Python function is an object:
def function(): print "hello" func = function func() # this will print "hello"
Now a decorator does this:
# decorator
def dec_function(func):
def wrapper():
func()
print "world"
return wrapper
# function to decorate
def function():
print "hello"
# replace original function by assigning the wrapper function to the function variable
function = dec_function(function)
# how decorators are used, this does the same as: function = dec_function(function)
# it does an in place swap so that it will work on class methods as well
@dec_function
def function():
print "hello"
# now calling the function() will result in "hello" "world" each on their own lineThere are lots of resources explaining decorators online for Python. I won't explain any further. I will just explain how they can be used for debugging. Some of you may have noticed that decorators ADD an extra function call each time the function is called. That is because the wrapper is called, then the original function from inside the wrapper. So having those extra calls is not necessarily desirable if it was only for debugging.The way I solved this was to use the #define trick from C:
# control thread check decorators
__check_script3d_thread__ = True
# check if this is the script3D_thread
def dec_IsScriptT3D_thread(func):
if __check_script3d_thread__:
def wrapper(self, *args, **kwargs):
assert(threading.current_thread().getName() == self.thread_name)
return func(self, *args, **kwargs)
return wrapper
else:
return func
# check if this is NOT the script3D_thread
def dec_NotScriptT3D_thread(func):
if __check_script3d_thread__:
def wrapper(self, *args, **kwargs):
assert(threading.current_thread().getName() != self.thread_name)
return func(self, *args, **kwargs)
return wrapper
else:
return funcThese decorators allow me to decorate a class method associated with a Thread derived object. If __check_script3d_thread__ is set to True then the wrapper is created and returned in place of the original function object. If it is False the original function object is returned and assigned to itself. This allows the decorator to be used when debugging the threading app, then later disabled for a "release" build. What originally drew me to this method was the __debug__ symbol Python uses. However __debug__ has to be disabled by a command line object and it also squashes asserts. Asserts can be used for other things besides conditions that might be fatal. So unless one can guarantee __debug__ is only used for asserts then it is best to use your own symbol to control your debug decorators.
So, in a way Python does have proprocessing capabilities as it does have an initial parse of the code before it is run. This initial parse can be used to define if objects are created based upon variables. Not exactly the same way as C preprocessors work, but enough to get the behavior we want.
About the author
I love programming, I love programming things that go click, whirr, boom. For organized T3D Links visit: http://demolishun.com/?page_id=67
#2
05/21/2012 (3:10 am)
Quote: I saw you still had 0 comments, and thought you might be lonely here by yourselfmay be that is because of python and compiler level talking. do not feel lonely and do not stop to write this type of thread.there are people like me who really love to read them and love to write less.
#3
can u plz send me a mail to muzaheed57@gmail.com ?
i was doing some study on custom scripting language implementation in c++.
may be i have found something to work with.or may be it is going to be another wastage of time.
so i need someone's suggestion on Compilation process.
08/20/2012 (3:56 am)
@frank,can u plz send me a mail to muzaheed57@gmail.com ?
i was doing some study on custom scripting language implementation in c++.
may be i have found something to work with.or may be it is going to be another wastage of time.
so i need someone's suggestion on Compilation process.

Torque Owner Dan Webb
PsyCandy Games
I'm going to go paint now.