The personal dumping grounds of an engineer, nerdist and human
about me
You have landed in the personal “blergh” of Gary Wright. I use this space to ramble about things such as network engineering, software development and life stuff…
It has been a wild few months since moving back here to the great PNW. Something that recently happened is obtaining an award for a recent join patent that I filed with a couple of close friends / engineers at Microsoft back in October. The patent is based on a concept of flexible vm disk images, which would incorporate a layer of metadata to describe the different configuration standards in which to be used, however do away with the need to store those individual images directly on disk. This would also in turn mean that you can speed up your deployments easily, without the extra overhead.
Sorry for the lack of posts lately, but I am in the process currently of moving from SVC back to good ol’ Seattle Washington. Still working on Microsoft, except now I will be back to an area that makes much more sense for an aging techy like me. Cost of living will certainly feel a lot better too. I will be back soon though, hopefully with better consistancy in updates as well.
I was recently chatting with someone that made the statement; “The only reason why I use my text editor is because of tab completion, I am a minimalist pythonista.”. I responded with, “If your a minimalist, why don’t you have tab completion enabled in the interpreter?” They were unaware of the ability to enable tab completion within python. Here is a my PSA on how to enable this behavior. :)
By following these instructions you will be able to enable tab-completion within your python shell.
Preperation steps:
Before enabling tab-completion, you may need to install 2 python modules (rlcompleter, readline). While these libraries are mostly included with python2.6+, some versions (OS X, for example), require the updated version to allow readline to function correctly.
shell
12
pip install readline
pip install rlcompleter
Step 1:
If you don’t already have a ~/.pyrc file, this command will create one for you, which is required for this trick to work.
shell
1
#> touch ~/.pyrc
Step 2:
Now we will create a file within your homedir which will instruct python to bind tab completion at python launch.
Now to ensure that your newly created ~/.pyrc file is executed each time python starts, add the following to your ~/.bashrc (or equiv. shell rc).
shell
12345
#> export PYTHONSTARTUP="[PATH TO PYRC FILE]/.pyrc"*OR TO MAKE THE CHANGE PERSIST TERMINAL CLOSURE
#> echo export PYTHONSTARTUP="[PATH TO PYRC FILE].pyrc" >> ~/.bashrc
Now to test, execute the following:
shell
1
#> source ~/.bashrc #reloads your ~/.bashrc file (if you added the entry to your ~/.bashrc, else ignore)
Now we will open the actual python shell, and view the tab completion goodness.
In the above example, I have imported the “os” module, typed “os.” and have pressed . Now all of the possible matched object names available within the module are shown. viola, python tab completion enabled.
When looking at the Python programming language, some of the most powerful and, unfortunately very under utilized “macro” design pattern within the language. One of the reasons I believe this to be the case is that most explanations of decorators suck. When you read the word “decorator” in regards to application development, most people generally think of http://www.amazon.com/gp/product/0201633612/ref=ase_bruceeckelA/ . While the “decorator” in Python can indeed be implemented in this fashion of design pattern, it is a very limited version of what decorators can actually accomplish.
I believe that decorators can actually be thought of as more “macros”, than the classical design pattern aforementioned above. http://en.wikipedia.org/wiki/Macro_(computer_science) , as defined by Wikipedia is “a rule or pattern that specifies how a certain input sequence (often a sequence of characters) should be mapped to a replacement output sequence (also often a sequence of characters) according to a defined procedure.” In short, if you have some metadata that you want to apply to any class, function or object, dress it up with a decorator.
Enough already, get to the example!
Decorators allow you to inject or modify code in functions or classes. Sounds a bit like Aspect-Oriented Programming (AOP) in Java, doesn’t it? So lets say you have an action that you would like to perform at the entry point (execution) or exit point (return) of a class, function. This is a prime example as when to use a decorator.
@myDecorator# The @myDecorator denotes the the application of a decorator
Function decorators
So by affixing a @decoratorname on a line directly above a function (or object), denotes the application of the results of a decorator function. In the previous example, when the python parser passes over the “myFunction()”, “myFunction()” is compiled and is, in turn, passed to the “myDecorator code block. This code block creates a function-like object that is ultimately what is returned when calling the “myFunction()” function. Confusing? Maybe this example will help.
decorator_example2.py
123456789101112131415
classmyDecorator(object):definit(self,func_object):print("Hello from inside myDecorator.init()")func_object()# Execute func_object() to prove it has been executed.defcall(self):print("Hello from inside myDecorator.call()")@myDecoratordefmyFunction():print("Hello from inside myFunction()")print("Finished decorating myFunction()")myFunction()
When you execute the above code, your results will look something like this:
output
1234
Hello from inside myDecorator.init()
Hello from inside myFunction()
Finished decorating myFunction()
Hello from inside myDecorator.call()
Note that the initialization of myDecorator(object) is executed when myFunction() is called. Due to the fact that we call “func_object()”, which is just myFunction() passed into the decorator class.init as a function object labeled “func_object”. Generally, you’ll pass the function object in the constructor and later use it in the call() method.
When myFunction() is called after it has been decorated, we get completely different behavior; the myDecorator.call() method is called instead of the original code. This is due to the fact that decoration replaces the original function object with the result of the decoration. In our case, the myDecorator object replaces myFunction.
This is it for the introduction to Python decorators, however look out for part II, coming soon… ☺