Python, it just fits your brain ... IntroductionThis sections features as a general get to know Python section in that it touches on the most profound theoretical and practical subjects. Main Usage AreasSo what is it that most people use Python for? Well, there are two main usage areas: There are many others too like for example scientific computing or robotics but those are areas which have a considerably smaller userbase than the two major areas mentioned above. PhilosophyIt is important for anyone involved with Python to at least understand a few basic/core ideas about the language itself:
GlossaryIt is strongly recommended to read the glossary! QuickStartThis subsection is a summary of the semantics and syntax in Python that can be read and followed along and which should not take longer than an hour. It is intended as a glance into Python for those who have not had contact with Python yet, or, for those who want a quick refresh of the cornerstones that makeup for most of Python's look and feel. Also, without further notice, all examples shown here are assumed Python 3 rather than Python 2. WRITEME Tips and TricksWRITEME BasicsThis section introduces the reader to basic principles and knowledge about the Python programming language and its ecosystem. FAQsThis section gathers FAQs about Python. What is the History behind Python?
1991 - Dutch programmer Guido van Rossum travels to Argentina for a Those who are looking for a serious answer, go use some search engine ;-] Zen of Python ... What is that?sa@wks:~$ python3.1 Python 3.1.1+ (r311:74480, Oct 12 2009, 05:40:55) [GCC 4.3.4] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import this The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one -- and preferably only one -- obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those! >>> sa@wks:~$ Everything made of Python of course should adhere to those plus principles of their own. Does Python have a Coding Standard?Is there a Cheat Sheet or RefCard for Python?Yes, the Internet has plenty of resources on the matter. Here is one of them. What Python Version do I run?sa@wks:~$ python >>> import sys >>> sys.version[:6] '3.1.1+' >>> import platform >>> platform.python_version() '3.1.1+' >>> sa@wks:~$ What is the difference between a Statement and an Expression?An expression is something e.g. What is a Module? What is a Package?We can think of modules as extensions/add-on/plugins that can be imported into Python to extend its capabilities beyond the core i.e. the interpreter itself. A module is usually just a file on the filesystem, containing source
code (statements, functions, classes, etc.) for a particular use case
e.g.
sa@sub:/tmp$ mkdir graphics; touch graphics/{draw,colorize}.py; ta graphics
graphics
|-- colorize.py
`-- draw.py
0 directories, 2 files
sa@sub:/tmp$ type ta
ta is aliased to `tree --charset ascii -a -I \.git*\|*\.\~*\|*\.pyc'
sa@sub:/tmp$
There are two ways how modules and/or packages are distributed:
When importing is has become good practice to import in the following order, one import per line:
One good example for a Python package can be found in Django where every project and the applications it contains is/are in fact Python packages. How do I get a list of available Modules?Use Polymorphism? Encapsulation? Inheritance?Roughly, these terms mean that we can use the same operations on objects of different types, and they will work as if by magic (polymorphism); we hide unimportant details of how objects work from the outside world (encapsulation), and we can create specialized classes of objects from general ones (inheritance). Coercion?Is the implicit conversion of an instance of one type to another
during an operation which involves two arguments of the same type. For
example, Without coercion, all arguments of even compatible types would have to
be normalized to the same value by the programmer e.g. What is a Class?A class is a datatype, same as a list, tuple, dictionary etc. are datatypes. Objects derived from one particular class are said to be instances of that class. Subclass? Superclass?When the objects belonging to class A form a subset of the objects belonging to class B, class A is called a superclass of class B. Class B is then called a subclass of class A. For example, cat can be a superclass to a subclass tiger. Lion can also be a subclass of the superclass cat — both, tigers and lions are cats, sorta, bulky though. Anyhow, let us not get off-topic: shark is not a subclass of cat since obviously a shark ain't no cat ... shark can have fish as its superclass. Yeah, yeah, yeah ... you smarty pants, the answer is yes! You can have your tigershark as well ;-] Metaclass?Please go here. Abstract Class? Abstract Base Class?Please go here. Context Manager?An object which controls the environment seen in a Static MethodWRITEME
Class MethodWRITEME Descriptor?It is actually a so-called protocol i.e. any object which defines the
methods When a class attribute is a descriptor, its special binding behaviour
is triggered upon attribute lookup. Normally, using Understanding descriptors is a key to a deep understanding of Python because they are the basis for many features including functions, methods, properties, class methods, static methods, and reference to super classes. How do I tell the Datatype of some Object?sa@wks:~$ type bp; bp bp is aliased to `bpython' >>> foo = 3 >>> bar = range(3) >>> type(foo) <type 'int'> >>> type(bar) <type 'list'> >>> sa@wks:~$ What is it about this PYTHONPATH variable?Well, actually we are not talking about What is the Difference between Distutils, Setuptools and Distribute?Although those tools have nothing to do with writing source code itself, they are needed to work with the whole Python ecosystem. Go here and here for more information. What is a Virtual Environment?A standard system has what is called a main Python installation also
known as global Python context/space i.e. a Python interpreter living
at Another way to have modules/packages installed would be to use virtualenv. It can be used to create isolated Python contexts/spaces i.e. those virtual environments can have their own Python interpreter as well as their own set of modules/packages installed and therefore have no connection with the global Python context/space whatsoever. Note that we can not just clone the global Python context/space or create an entirely separated Python context/space to work with, but we can also link any directories into any virtual environment. This means ultimate flexibility without risking to damage the existing main Python installation also known as global Python context/space. Why has Debian ../dist-packages Directories?Before we actually answer that, let us have a look at the big picture of having public and private installations of Python modules and packages. Let us also have a glance at the difference about the main Python installations (also known as global Python context/space) and virtual environments: By default Python modules/packages are searched in the current working
directory first, next in the directories listed in the The full truth is that Python initializes That said, there are generally three ways to install Python modules/packages — there are public ones and private ones with regards to the systems main Python installation (also known as global Python context/space) and then there are virtual environments which are either clones of the global Python context/space or which are entirely separated Python contexts/spaces on their own:
Right now we are only looking at the global Python context/space and leave aside virtual environments. We are also just looking at the public modules/packages subset and not how to handle private modules/packages within the global Python context/space. Finally, why Debian has ../dist-packages directories:The installation location for Python code packaged by Debian is the
system Python modules directory, Tools used for packaging Python source code for Debian like
In case we are on Python 2.6 or later and do not use APT but some
other means (e.g. When binary packages ship identical source code for multiple Python
versions, for instance Summary, assuming Python >= 2.6
Note the difference between How does Python find Code on the Filesystem?If we have code (modules or packages) somewhere on the filesystem that
we want Python to know about, we need to import that code using the
So how do we tell Python about the places where it should look for
code? The variable
Before we start, let us take a look at sa@wks:~$ python3.1 Python 3.1.1+ (r311:74480, Oct 12 2009, 05:40:55) [GCC 4.3.4] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> dir() ['__builtins__', '__doc__', '__name__', '__package__'] >>> import pprint, sys >>> pprint.pprint(sys.path) ['', '/usr/lib/python3.1', '/usr/lib/python3.1/plat-linux2', '/usr/lib/python3.1/lib-dynload', '/usr/lib/python3.1/dist-packages', '/usr/local/lib/python3.1/dist-packages'] If we decided to add our own or some third party code without adding a
new directory to
If we want/have to add another directory to
Manually adding to sys.pathThis one is straight forward as we only need to append to
>>> import os
>>> sys.path.append('/tmp'); sys.path.append(os.path.expanduser('~/0/django'))
>>> pprint.pprint(sys.path)
['',
'/usr/lib/python3.1',
'/usr/lib/python3.1/plat-linux2',
'/usr/lib/python3.1/lib-dynload',
'/usr/lib/python3.1/dist-packages',
'/usr/local/lib/python3.1/dist-packages',
'/tmp',
'/home/sa/0/django']
>>>
Adding directories manually is quick and certainly nice while doing
development/testing but it is not what we want for some permanent
setup like for example a long-term development project or a production
site. For those, we want to add directories to Automatically adding to sys.pathWhen a module named sa@wks:~$ echo $PATH /usr/local/bin:/usr/bin:/bin:/usr/games:/home/sa/0/bash sa@wks:~$ When Most Linux distributions include Python as a standard part of the
system, so sa@wks:~$ python3.1 Python 3.1.1+ (r311:74480, Oct 12 2009, 05:40:55) [GCC 4.3.4] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import sys; sys.prefix '/usr' >>> sa@wks:~$ So now we know how finding code on the filesystem works. This however
does not help us much since we do not want to use any of the default
paths/directories listed in
Although the standard method so far is to add directories to
So what do we do? Piece of cake, we use All we need to do is to put our
1 sa@wks:/tmp$ mkdir test; cd test; echo -e "foo\nbar" > our_path_file.pth
2 sa@wks:/tmp/test$ mkdir foo bar
3 sa@wks:/tmp/test$ echo 'print("inside foo.py")' > foo/foo.py
4 sa@wks:/tmp/test$ echo 'print("inside bar.py")' > bar/bar.py
5 sa@wks:/tmp/test$ type ta
6 ta is aliased to `tree -a -I \.git*\|*\.\~*\|*\.pyc'
7 sa@wks:/tmp/test$ ta ../test/
8 ../test/
9 |-- bar
10 | `-- bar.py
11 |-- foo
12 | `-- foo.py
13 `-- our_path_file.pth
14
15 2 directories, 3 files
16 sa@wks:/tmp/test$ cat our_path_file.pth
17 foo
18 bar
19 sa@wks:/tmp/test$ python3.1
20 Python 3.1.1+ (r311:74480, Oct 12 2009, 05:40:55)
21 [GCC 4.3.4] on linux2
22 Type "help", "copyright", "credits" or "license" for more information.
23 >>> import pprint, sys, site
24 >>> pprint.pprint(sys.path)
25 ['',
26 '/usr/lib/python3.1',
27 '/usr/lib/python3.1/plat-linux2',
28 '/usr/lib/python3.1/lib-dynload',
29 '/usr/lib/python3.1/dist-packages',
30 '/usr/local/lib/python3.1/dist-packages']
31 >>> site.addsitedir('/tmp/test')
32 >>> pprint.pprint(sys.path)
33 ['',
34 '/usr/lib/python3.1',
35 '/usr/lib/python3.1/plat-linux2',
36 '/usr/lib/python3.1/lib-dynload',
37 '/usr/lib/python3.1/dist-packages',
38 '/usr/local/lib/python3.1/dist-packages',
39 '/tmp/test',
40 '/tmp/test/foo',
41 '/tmp/test/bar']
42 >>> import foo
43 inside foo.py
44 >>> import foo
45 >>> import bar
46 inside bar.py
Python now finds our modules
Certainly, no one really cares to use What I often do is to add to
47 >>> site.USER_SITE
48 '/home/sa/.local/lib/python3.1/site-packages'
49 >>> import os
50 >>> dir()
51 ['__builtins__', '__doc__', '__name__', '__package__', '__warningregistry__', 'bar', 'foo', 'os', 'pprint', 'site', 'sys']
52 >>> mypth = os.path.join(site.USER_SITE, 'mypath.pth')
53 >>> print (mypth)
54 /home/sa/.local/lib/python3.1/site-packages/mypath.pth
55 >>> module_paths_to_add_to_sys_path = ["/home/sa/0/django", "/home/sa/0/bash"]
56 >>> if not os.path.isdir(site.USER_SITE):
57 ... os.makedirs(site.USER_SITE)
58 ...
59 >>> with open(mypth, "a") as f:
60 ... f.write("\n".join(module_paths_to_add_to_sys_path))
61 ... f.write("\n")
62 ...
63 33
64 1
65 >>> pprint.pprint(sys.path)
66 ['',
67 '/usr/lib/python3.1',
68 '/usr/lib/python3.1/plat-linux2',
69 '/usr/lib/python3.1/lib-dynload',
70 '/usr/lib/python3.1/dist-packages',
71 '/usr/local/lib/python3.1/dist-packages',
72 '/tmp/test',
73 '/tmp/test/foo',
74 '/tmp/test/bar']
75 >>> site.addsitedir(site.USER_SITE)
76 >>> pprint.pprint(sys.path)
77 ['',
78 '/usr/lib/python3.1',
79 '/usr/lib/python3.1/plat-linux2',
80 '/usr/lib/python3.1/lib-dynload',
81 '/usr/lib/python3.1/dist-packages',
82 '/usr/local/lib/python3.1/dist-packages',
83 '/tmp/test',
84 '/tmp/test/foo',
85 '/tmp/test/bar',
86 '/home/sa/.local/lib/python3.1/site-packages',
87 '/home/sa/0/django',
88 '/home/sa/0/bash']
89 >>>
90 sa@wks:/tmp/test$
What is a Decorator?Please go here. Why would I want to pass a Function to another Function?There are two reasons why we want to do that:
Decorator vs AdapterThe decorator design pattern differs from the adapter design pattern in that decorators wrap functions or methods whereas adapters wrap classes or instances thereof. An adapter wraps a class foo or an object/instance thereof so that it works/behaves in a context intended for a class or an object/instance bar. What is a Callback?A callback is a function provided by the consumer of an API (Application Programming Interface) that the API can then turn around and invoke (calling us back). For example, if we setup a Dr.'s appointment, we can give them our phone number, so they can call us the day before to confirm the appointment. A callback is like that, except instead of just being a phone number, it can be arbitrary instructions like send us an email at this address, and also call our secretary and have her put it in our calendar. Callbacks are often used in situations where an action is asynchronous. If we need to call a function, and immediately continue working, we can not sit there wait for its return value to let us know what happened, so we provide a callback. When the function has finished its asynchronous work it will invoke our callback code with some predetermined arguments (usually some we supply, and some about the status and result of the asynchronous action we requested). If the Dr. is out of the office, or they are still working on the schedule, rather than having us wait on hold until he gets back, which could be several hours, we hang up, and once the appointment has been scheduled, they call us. Python will invoke our callback code with any arguments we supply and the result of its asynchronous computation, once this asynchronous computation has finished executing. Let us look at some example:
sa@wks:~$ python3.1
Python 3.1.1+ (r311:74480, Oct 12 2009, 05:40:55)
[GCC 4.3.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def callback(nums):
... """ The callback function """
... return sum(nums) * 2
...
>>> def another_callback(nums):
... """ Yet another callback function """
... return sum(nums) * 3
...
>>> def strange_sum(nums, cb):
... """
... Asynchronous computation: Returns the sum, if less than 10
... else returns the result of calling the callback function cb(),
... which must accepts one list argument
... """
... if sum(nums) > 10:
... print("no callback function used")
... else:
... return cb(nums)
...
>>> print (strange_sum([1, 10], callback))
no callback function used
None
>>> print (strange_sum([3, 2], another_callback))
15
>>> print (strange_sum([6,4,3], another_callback))
no callback function used
None
>>>
sa@wks:~$
So basically, a callback is a function that we pass as an argument (to
another function that is; functions itself are only values in Python
i.e. calling What is a Handler?A handler is a asynchronous callback subroutine that can be told to do some work for us and call back when it is done (see Dr.'s appointment example). What is setup.py?
Some packages are pure Python and are only byte-compiled, other packages may, for example, contain native C code which will require a native compiler like gcc or cl and some Python interfacing module like swig or pyrex. Generally What is setup.cfg?It is a configuration file local to some package which is used to
record configuration data for a particular package. At first it looks at the system-wide configuration file e.g.
Any of those levels overrides the former one e.g. personal overrides system-wide, package-local overrides personal and of course, package-local also overrides system-wide. What is __init__.py for?Files named Every time we use What is site.py for?
What is EAFP?EAFP (Easier to ask for Forgiveness than Permission) is a
programming principle how to approach problems/things when
programming. This clean and fast style is characterized by the
presence of many It is nothing Python specific but can actually be found with many programming languages. With Python however, because of it is nature, adhering to this principle works quite well. In Python EAFP is generally preferred over LBYL (Look before you Leap), which is the contrary principle and, for example, the predominant coding style with C. Monkey Patching?A monkey patch is a way to extend and/or modify the runtime code of dynamic languages such as Smalltalk, JavaScript, Objective-C, Ruby, Perl, Python, Groovy, etc. without altering its on-disk source code. In Python, the term monkey patch only refers to dynamic modifications of a class at runtime based on the intent to patch existing methods in an external class as a workaround to a bug and/or feature which does not act as we desire. Examples of using monkey patching are
In general however it is fair to say that one should refrain from monkey patching since it mostly introduces more problems than it solves.
Even if monkey patching is not used, many people see a problem with the availability of the feature, since the ability to use monkey patching in a programming language is incompatible with enforcing strong encapsulation, as required by the object-capability model, between objects. Bottom line is, one should not use monkey patching for the afore mentioned reasons and many more ... What is a Method Stub?Please go here for further information. What is a Finder / Loader / Importer?To use functionality that is not built-in with Python core
i.e. the interpreter itself, we need to get it from somewhere. This is
called importing — basically everything that involves the This process of importing is, as many other things, specified by a so-called protocol. The Importer protocol involves two objects: a finder and a loader.
In many cases the finder and loader are one and the same object i.e.
I see this __future__ thing a lot? What is it?Basically what the name promises, it is a module that brings future
features which are not enabled with the current version of Python core
(the interpreter) by default. Simply using Garbage Collection?Not the thing your neighbours are talking about when referring to your car but rather the automatic memory management of Python which is based on its dynamic type system and a combination of reference counting and garbage collection.
In a nutshell: once the last reference to an object is removed, the object is deallocated ... that is, left floating around in memory until deleted/overwritten. The memory it occupied is said to be freed and possibly immediately reused by another (new) object. Python's memory management is smart enough to detect and break cyclic references between objects that might otherwise occupy memory indefinitely, which in its worst case might cause memory shortage. Reference CountThe number of references to an object. When the reference count of an object drops to zero, it is deallocated. Reference counting is generally not visible to Python code, but it is a key element of the CPython implementation. The Mutable vs Immutable?Immutable objects cannot change their value and keep their id() as
mutable ones can. In other words, if we want to alter an immutable
object, we need to create a new/different one — the new one will have
a different Immutable objects play an important role in places where a constant hash value is needed, for example as a key in a dictionary. To name a few immutable objects: numbers, strings, tuples, frozensets, byte, etc. What all those have in common is that they are Python built-in datatypes. It is fair to say that immutable datatypes can be thought of as the basic building blocks used to assemble more complex datatypes e.g. if we use a class to create ourselves a particular datatype used for our individual web application, this class, or rather instances thereof, would probably be mutable but some of its attributes might not be. In a nutshell: most Python built-in datatypes are immutable (cannot
change their value without changing their IterableA container object capable of returning its members one at a time rather than all at once. Examples of iterable objects include sequence types such as Iterables can be used in a for loop and in many other places where a
sequence is needed ( When using iterable objects, it is usually not necessary to call
IteratorAn object representing a stream of data. Repeated calls to the
iterator's When there is no more data available from the stream, a Iterators are required to have an One notable exception is code which attempts multiple iteration
passes. A container object (such as a list) produces a fresh new
iterator each time we pass it to the GeneratorA generator is a function which returns an iterator. It looks like a
normal function except that it contains Each Generator ExpressionAn expression that returns an iterator. It looks like a normal
expression followed by a >>> sum(i*i for i in range(10)) # sum of squares 0, 1, 4, ... 81 285 Global Interpreter LockA GIL (Global Interpreter Lock) is a mutual exclusion lock held by an interpreter thread. Its use is to avoid sharing code that is not thread-safe with other threads. There is always one GIL for one interpreter process. Problem is, while this gives better performance on single-core machines, it fails to scale for multiprocessor machines. Is there a better Python Shell/Interpreter?Yes, yes, there is! There is iPython and then there is bpython which I have come to love. It is packaged with Debian sa@wks:~$ dpl bpy* | grep ii ii bpython 0.9.5.2-1 fancy curses interface to the Python interactive sa@wks:~$ There is also http://bpaste.net, a pastebin site. This for itself is no big deal. The fact that bpython can ship off its contents (what we typed) at the press of a button, right into bpaste.net, however is — I often use it to sketch things in a live interpreter session and then quickly show it to folks while we talk on IRC, maybe during debugging some code and stuff like that. There are a lot more goodies at our disposal like for example
Django support. Most of it can be configured in sa@wks:~$ cat .bpython/config | grep -v \# | grep . [general] auto_display_list = True syntax = True arg_spec = True hist_file = ~/.pythonhist hist_len = 5000 tab_length = 4 color_scheme = suno [keyboard] pastebin = F8 save = C-s And then there is of course a custom theme we might use sa@wks:~$ cat .bpython/suno.theme | grep -v \# | grep . [syntax] keyword = y name = W comment = w string = M error = r number = G operator = Y punctuation = y token = C [interface] background = d output = w main = w prompt = w prompt_more = w sa@wks:~$ The coolest thing about bpython is probably autocompletion, inline syntax highlighting, the fact that is shows us the expected parameter list as we type and last but not least, the possibility to rewind what we typed not just graphically but also internally i.e. the results of each such expression we typed. Below is a screenshot showing a few of the just mentioned things: Using bpython with DjangoUsually, being at the root of a Django project, which we created using
sa@wks:~/0/django/myproject$ python manage.py help shell | grep Runs Runs a Python interactive interpreter. Tries to use IPython, if it's available. sa@wks:~/0/django/myproject$ If however we want The rationale behind Note that whatever file Furthermore, we can also change the prompts Now that we have
try:
from django.core.management import setup_environ
import settings
setup_environ(settings)
print 'imported django settings'
except:
pass
This way, bpython (or even just the ordinary python interpreter),
imports the django environment for us. Let us have a look — we are at
the root of the project 1 sa@wks:~/0/django/myproject$ ta -L 2 2 . 3 |-- __init__.py 4 |-- locale 5 | `-- de 6 |-- manage.py 7 |-- polls 8 | |-- __init__.py 9 | |-- admin.py 10 | |-- models.py 11 | |-- tests.py 12 | `-- views.py 13 |-- settings.py 14 |-- sqlite3.db 15 |-- templates 16 | |-- admin 17 | `-- polls 18 `-- urls.py 19 20 6 directories, 10 files 21 sa@wks:~/0/django/myproject$ cat /home/sa/.pythonrc 22 sa@wks:~/0/django/myproject$ bpython 23 >>> dir() 24 ['__builtins__', '__doc__', '__name__', 'help'] 25 >>> 26 27 28 [ here we use some editor to put our code into ~/.pythonrc ...] 29 30 31 32 sa@wks:~/0/django/myproject$ cat /home/sa/.pythonrc 33 try: 34 from django.core.management import setup_environ 35 import settings 36 setup_environ(settings) 37 print 'imported django settings' 38 except: 39 pass 40 sa@wks:~/0/django/myproject$ source /home/sa/.bashrc 41 sa@wks:~/0/django/myproject$ bpython 42 imported django settings 43 >>> dir() 44 ['__builtins__', '__doc__', '__name__', 'help', 'settings', 'setup_environ'] 45 >>> Note the different output from lines 24 and 44 — this comes from
lines 33 to 39 which were not active in line 22. Line 40 is just to
source So, what we have so far is great since we can, for example, access our
settings from an interpreter session without the need to load anything
explicitly i.e. we would not have to issue line 46 which I just did so
it can be seen where line 52 gets its information from ( 46 sa@wks:~/0/django/myproject$ grep -A5 TEMPLATE_DIRS settings.py | grep -v \# 47 TEMPLATE_DIRS = ( 48 '/home/sa/0/django/myproject/templates' 49 ) 50 sa@wks:~/0/django/myproject$ bpython 51 imported django settings 52 >>> settings.TEMPLATE_DIRS 53 '/home/sa/0/django/myproject/templates' 54 >>> To put the cherry on top of this convenience, lets add what is
available trough using django-extensions namely the 55 sa@wks:~/0/django/myproject$ python manage.py help shell_plus | grep Like 56 Like the 'shell' command but autoloads the models of all installed Django apps. We add to
57 sa@wks:~/0/django/myproject$ cat ~/.pythonrc
58 try:
59 from django.core.management import setup_environ
60 import settings
61 setup_environ(settings)
62 print 'imported django settings'
63 try:
64 exec_strs = ["from %s.models import *"%apps for apps in settings.INSTALLED_APPS ]
65 for x in exec_strs:
66 try:
67 exec(x)
68 except:
69 print 'Not imported for %s' %x
70 print 'imported django models'
71 except:
72 pass
73 except:
74 pass
75 sa@wks:~/0/django/myproject$ source /home/sa/.bashrc; bpython
76 imported django settings
77 imported django models
78 >>> import pprint
79 >>> pprint.pprint(dir())
80 ['ADDITION',
81 'AnonymousUser',
82 'CHANGE',
83 'Choice',
84 'ContentType',
85 'ContentTypeManager',
86 'DELETION',
87 'EmptyManager',
88 'Group',
89 'ImproperlyConfigured',
90 'LogEntry',
91 'LogEntryManager',
92 'Message',
93 'Permission',
94 'Poll',
95 'RequestSite',
96 'SITE_CACHE',
97 'Session',
98 'SessionManager',
99 'Site',
100 'SiteManager',
101 'SiteProfileNotAvailable',
102 'UNUSABLE_PASSWORD',
103 'User',
104 'UserManager',
105 '__builtins__',
106 '__doc__',
107 '__name__',
108 'apps',
109 'auth',
110 'base64',
111 'check_password',
112 'datetime',
113 'exec_strs',
114 'get_hexdigest',
115 'help',
116 'mark_safe',
117 'md5_constructor',
118 'models',
119 'pickle',
120 'pprint',
121 'quote',
122 'settings',
123 'setup_environ',
124 'sha_constructor',
125 'smart_str',
126 'smart_unicode',
127 'urllib',
128 'x']
129 >>> datetime.datetime.utcnow()
130 datetime.datetime(2009, 12, 12, 22, 10, 8, 361387)
131 >>>
132 sa@wks:~/0/django/myproject$ cat polls/models.py
133 from django.db import models
134 import datetime
135
136
137 class Poll(models.Model):
138 question = models.CharField(max_length=200)
139 pub_date = models.DateTimeField('date published')
140 def __unicode__(self):
141 return self.question
142 def was_published_today(self):
143 return self.pub_date.date() == datetime.date.today()
144 was_published_today.short_description = 'Published today?'
145
146
147 class Choice(models.Model):
148 poll = models.ForeignKey(Poll)
149 choice = models.CharField(max_length=200)
150 votes = models.IntegerField()
151 def __unicode__(self):
152 return self.choice
153 sa@wks:~/0/django/myproject$
This is great! Note that the models Last but not least, we can use bpython's ability to save the current session to a file — this file is then used to load our former session into bpython again, effectivelly allowing us to resume our work where we left off before. We use the
sa@wks:~/0/django/mysite$ bpython
imported django settings
imported django models
>>> print 'funky donkey at work'
funky donkey at work
[ here I used C+s to save the current session to startup.py ... ]
>>>
sa@wks:~/0/django/mysite$ cat startup.py
# OUT: imported django settings
# OUT: imported django models
print 'funky donkey at work'
# OUT: funky donkey at work
sa@wks:~/0/django/mysite$ cat /home/sa/.pythonrc
# import saved bpython session if available
try:
from startup import *
except:
pass
# do for bpython what shell_plus from django-extensions does for iPython
try:
from django.core.management import setup_environ
import settings
setup_environ(settings)
print 'imported django settings'
try:
exec_strs = ["from %s.models import *"%apps for apps in settings.INSTALLED_APPS ]
for x in exec_strs:
try:
exec(x)
except:
print 'Not imported for %s' %x
print 'imported django models'
except:
pass
except:
pass
sa@wks:~/0/django/mysite$ source /home/sa/.bashrc; bpython
funky donkey at work
imported django settings
imported django models
>>>
sa@wks:~/0/django/mysite$
Using bpython with multiple Python versionsCurrently (May 2010) we can run bpython with those Python versions: 2.4, 2.5, 2.6, 2.7 and 3. The default version is the one our system links to: sa@wks:~$ type ll; ll $(which python) ll is aliased to `ls -lh' lrwxrwxrwx 1 root root 9 Jan 23 07:56 /usr/bin/python -> python2.5 sa@wks:~$ However, we can use others as well by simply creating an alias in our
sa@wks:~$ grep bpython .bashrc
###_ . bpython
alias bp='bpython'
alias bp26='python2.6 -m bpython.cli'
alias bp31='python3.1 -m bpython.cli'
sa@wks:~$
We can then type Datatypes and StructuresPython is a dynamically typed language with a strong type system.
Bei vielen Algorithmen hängt der Ressourcenbedarf, also sowohl die benötigte Laufzeit als auch der Speicherplatzbedarf, von der Verwendung geeigneter Datenstrukturen ab. LiteralsStringsDecimalContainers also known as CollectionsSequencesOrdered Sequences
Unordered SequencesMappingsSyntax and SemanticsOne of the things I like most about Python is that it is not as wordy as Java and not as cryptic as Perl (once you know Python, you will stay away from those two anyways) but just a great language with an pragmatic approach to software development. TheoryStackless Python
Type System
Scope / Namespaces
Polymorphism
Encapsulation
Functions in Python are so-called First-Class objects. Introspection
Aspect Oriented ProgrammingMagic MethodsMetaprogramming with Python
MetaclassA basic blueprint to build other/enhanced classes with ...
Abstract (Base) ClassIts main use is to define and build interfaces ...
ReflectionDesign Patterns
A design pattern is a general reusable solution to a commonly This is a huge subject, ready to fill bookshelves on its own. This subsection will look at design patterns at code-level with regards to Python i.e. not all known design patterns exist in Python respectively make sense using them when programming in Python (this is true for any other language as well). Design patterns can be divided into several categories: Creational Patterns, Structural Patterns, Behavioral Patterns and Concurrency Patterns. They are described using the concepts of delegation, aggregation, and consultation. There also exists another classification that has the notion of architectural design patterns which may be applied at the architecture level of the software such as the MVC (Model-View-Controller) pattern. This high-level view on design patterns is not covered here. Creational PatternCreational design patterns are design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. The basic form of object creation could result in design problems or added complexity to the design. Creational design patterns solve this problem by somehow controlling this object creation. SingletonStructural PatternStructural design patterns are design patterns that ease the design by identifying a simple way to realize relationships between entities. FacadeProxyAdapterDecoratorWe already know the difference between a decorator and an adapter. What a decorator does is attach additional responsibilities to an object dynamically, keeping the same interface. Decorators provide a flexible alternative to subclassing for extending functionality. Subclassing adds behaviour at compile time whereas decorating can provide new behaviour at runtime. Decorators vs. the Decorator PatternFirst, we need to understand that the word decorator in Python was used with some trepidation, because there was concern that it would be completely confused with the Decorator pattern from the Design Patterns book. At one point other terms were considered for the feature, but decorator seems to be the one that sticks. Indeed, we can use Python decorators to implement the Decorator pattern, but that is an extremely limited use of it. Python decorators, I think, are best equated to macros. Example:A decorator wraps a function i.e. the two below are equivalent This orig_function = my_decorator(orig_function) is equivalent to
@my_decorator
def orig_function():
print "inside orig_function"
When the compiler passes over this code, Behavioral PatternBehavioral design patterns are design patterns that identify common communication patterns between objects and realize these patterns. By doing so, these patterns increase flexibility in carrying out this communication. Delegation
StrategyChain of Responsibility
ObserverVisitorTemplateConcurrency PatternConcurrency patterns are those types of design patterns that deal with multi-threaded programming paradigm. PracticeThis section provides miscellaneous information within regards to Python. Package / Distribute / InstallThis section is all about packaging, distributing and installing Python software. History
This text is a literal copy take from Martijn Faassen blog where he describes the current (February 2010) state of packaging/distributing Python software. The reason I (Markus Gattol) include it here in full length again is that I find it utterly important for anyone to understand the pig picture about why things are the way the are today and what happened during the last ten or so years so that we finally ended up with a pretty amazing toolchain and infrastructure in order to develop, package, distribute and share Python software. IntroductionEarlier this year I (read Martijn Faassen) was at PyCon in the US. I had an interesting experience there: people were talking about the problem of packaging and distributing Python libraries. People had the impression that this was an urgent problem that had not been solved yet. I detected a vibe asking for the Python core developers to please come and solve our packaging problems for us. I felt like I had stepped into a parallel universe. I have been using powerful tools to assemble applications from Python packages automatically for years now. Last summer at EuroPython, when this discussion came up again, I maintained that packaging and distributing Python libraries is a solved problem. I put the point strongly, to make people think. I fully agree that the current solutions are imperfect and that they can be improved in many ways. But I also maintain that the current solutions are indeed solutions. There is now a lot of packaging infrastructure in the Python community, a lot of technology, and a lot of experience. I think that for a lot of Python developers the historical background behind all this is missing. I will try to provide one here. It is important to realize that progress has been made, step by step, for more than a decade now, and we have a fine infrastructure today. I have named some important contributors to the Python packaging story, but undoubtedly I have also not mentioned a lot of other important names. My apologies in advance to those I missed. The dawn of Python packagingThe Python world has been talking about solutions for packaging and distributing Python libraries for a very long time. I remember when I was new in the Python world about a decade ago, in the late 90s, it was considered important and urgent that the Python community implement something like Perl's CPAN. I am sure too that this debate had started long before I started paying attention. I have never used CPAN, but over the years I have seen it held up by many as something that seriously contributes to the power of the Perl language. With CPAN, I understand, you can search and browse Perl packages and you can install them from the net. So, lots of people were talking about a Python equivalent to CPAN with some urgency. At the same time, the Python world did not seem to move very quickly on this front... DistutilsThe Distutils SIG (special interest group) was started in late 1998.
Greg Ward in the context of this discussion group started to create
Distutils about this time. Distutils allows you to structure your
Python project so that it has a setup.py. Through this MetadataWe now had a way to distribute and install Python packages, if we did the distribution ourselves. We did not have a centralized index (or catalog) of packages yet, however. To work on this, the Catalog SIG was started in the year 2000. The first step was to standardize the metadata that could be cataloged by any index of Python packages. Andrew Kuchling drove the effort on this, culminating in PEP 241 in 2001, later updated by PEP 314. Distutils was modified so it could work with this standardized metadata. PyPI (Python Project Index)In late 2002, Richard Jones started work on the PyPI. PyPI was initially known as the Cheeseshop. Until around January 2010 it was then known as Python Package Index which turned out to not be appropriate anymore since the Python community now distributes so-called Projects rather than Packages. The first work on an implementation started, and PEP 301 that describes PyPI was also created then. Distutils was extended so the metadata and packages themselves could be uploaded to this package index. By 2003, the Python package index was up and running. The Python world now had a way to upload packages and metadata to a
central index. If we then manually downloaded a package we could
install it using SetuptoolsPhillip Eby started work on Setuptools in 2004. Setuptools is a whole range of extensions to Distutils such as from a binary installation format (eggs), an automatic package installation tool, and the definition and declaration of scripts for installation. Work continued throughout 2005 and 2006, and feature after feature was added to support a whole range of advanced usage scenarios. By 2005, you could install packages automatically into your Python interpreter using easy_install. Dependencies would be automatically pulled in. If packages contained C code it would pull in the binary egg, or if not available, it would compile one automatically. The sheer amount of features that Setuptools brings to the table must be stressed: namespace packages, optional dependencies, automatic manifest building by inspecting version control systems, web scraping to find packages in unusual places, recognition of complex version numbering schemes, and so on, and so on. Some of these features perhaps seem esoteric to many, but complex projects use many of them. The Problems of Shared PackagesThe problem remained that all these packages were installed into your Python interpreter. This is icky. People's site-packages directories became a mess of packages. You also need root access to easy_install a package into your system Python. Sharing all packages in a direcory in general, even locally, is not always a good idea: one version of a library needed by one application might break another one. Solutions for this emerged in 2006. VirtualenvIan Bicking drove one line of solutions: virtual-python, which evolved into workingenv, which evolved into virtualenv in 2007. The concept behind this approach is to allow the developer to create as many fully working Python environments as they like from a central system installation of Python. When the developer activates the virtualenv, easy_install respectively its successor pip will install all packages into its the virtualenv's site-packages directory. This allows you to create a virtualenv per project and thus isolate each project from each other. BuildoutIn 2006 as well, Jim Fulton created Buildout, building on Setuptools
and easy_install. Buildout can create an isolated project environment
like virtualenv does, but is more ambitious: the goal is to create a
system for repeatable installations of potentially very complex
projects. Instead of writing an The brilliance of Buildout is that it is easily extensible with new installation recipes. These recipes themselves are also installed automatically from PyPI. This has spawned a whole ecosystem of Buildout recipes that can do a whole range of things, from generating documentation to installing MySQL. Since Buildout came out of the Zope world, Buildout for a long time was seen as something only Zope developers would use, but the technology is not Zope-specific at all, and more and more developers are picking up on it. In 2008, Ian Bicking created an alternative for easy_install called
Setuptools and the Standard LibraryThe many improvements that Setuptools brought to the Python packaging story had not made it into the Python Standard Library, where Distutils was stagnating. Attempts had been made to bring Setuptools into the standard library at some point during its development, but for one reason or another these efforts had foundered. Setuptools probably got where it is so quickly because it worked around often very slow process of adopting something into the standard library, but that approach also helped confuse the situation for Python developers. Last year Tarek Ziade started looking into the topic of bringing improvements into Distutils. There was a discussion just before PyCon 2009 about this topic between various Python developers as well, which probably explains why the topic was in the air. I understood that some decisions were made:
DistributeBy 2008, Setuptools had become a vital part of the Python development infrastructure. Unfortunately the Setuptools development process has some flaws. It is very centered around Phillip Eby. While he had been extremely active before, by that time he was spending a lot less energy on it. Because of the importance of the technology to the wider community, various developers had started contributing improvements and fixes, but these were piling up. This year, after some period of trying to open up the Setuptools project itself, some of these developers led by Tarek Ziade decided to fork Setuptools. The fork is named Distribute. The aim is to develop the technology with a larger community of developers. One of the first big improvements of the Distribute project is Python 3 support. Quite understandably this fork led to some friction between Tarek, Phillip and others. I trust that this friction will resolve itself and that the developers involved will continue to work with each other, as all have something valuable contribute. Operating System PackagingOne point that always comes up in discussions about Python packaging tools is operating system packaging. In particular Linux distributions have developed extremely powerful ways to distribute and install complex libraries and application, manage versions and dependencies and so on. Naturally when the topic of Python packaging comes up, people think about operating system packaging solutions like this. Let me start off that I fully agree that Python packaging solutions can learn a lot from operating system packaging solutions. Why don't we just use a solution like that directly, though? Why is a Python specific packaging solution necessary at all? There are a number of answers to this. One is that operating packaging solutions are not universal: if we decided to use Debian's system, what would we do on Windows? The most important answer however is that there are two related but also very different use cases for packaging:
The Python packaging systems described above primarily try to solve the development use case: I am a Python developer, and I am developing multiple projects at the same time, perhaps in multiple versions, that have different dependencies. I need to reuse packages created by other developers, so I need an easy way to depend on such packages. These packages are sometimes in a rather early state of development, or perhaps I am even creating a new one. If I want to improve such a package I depend on, I need an easy way to start hacking on it. Operating system packaging solutions as I have seen them used are ill suited for the development use case. They are aimed at creating a single consistent installation that is easy to upgrade with an eye on security. Backwards compatibility is important. Packages tend to be relatively mature. For all I know it might indeed be possible to use an operating system packaging tool as a good development packaging tool. But I have heard very little about such practices. Please enlighten me if you have. It is also important to note that the Python world is not as good as
it should be at supporting operating system packaging solutions. The
freeing up of package metadata from the confines of the ConclusionsWe are now in a time of consolidation and opening up. Many of the solutions pioneered by Setuptools are going to be polished to go into the Python Standard Library. At the same time, the community surrounding these technologies is opening up. By making metadata used by Distutils and Setuptools more easily available to other systems, new tools can also more easily be created. The Python packaging story had many contributors over the years. We now have a powerful infrastructure. Do we have an equivalent to CPAN? I do not know enough about CPAN to be sure. But what we have is certainly useful and valuable. In my parallel universe, I use advanced Python packaging tools every day, and I recommend all Python programmers to look into this technology if they have not already. Join me in my parallel universe! Update: I just found out there was a huge thread on python-dev about this in the last few days which focused around the question whether we have the equivalent of CPAN now. One of them funny coincidences... History ContinuesAt PyCon 2010 the decision was made to basically exchange distutils with distutils2 where distutils2 is a fork of Distribute. Setuptools, distutils and Distribute are going to die (read phased out). pip will stay and once distutils is replaced by distutils2, it will work with it as it does now (March 2010) with Distribute. Take a look at this picture:
The distutils module is currently part of the standard library and will be until Python 3.3 — it will be discontinued in Python 3.3 in favor of distutils2 which will be backwards compatible down to Python 2.4. Glossary
WRITEME ExamplesJust provide the below links and then show a bunch of examples for each step i.e. package, distribute, install; thereby using the tools (pip, distribute, etc.) listed below
WRITEME Tools / UtilsThis section provides information on what tools I use on a daily basis when it comes to developing/deploying/administer/test/etc. Python software. Virtualenv / Virtualenvwrapper / Virtualenv-commandsThis one is all about gaining freedom — the kind of freedom that allows us to be creative, have fun and get things done quickly and in a straight forward and simple manner. So, what is it that virtualenv does in a nutshell? By using By default we have symlinks going from those virtual environments out
and going into our global Python context/space e.g. to the Python
interpreter. However, we can also make those sandboxes totally
separated from the rest of the system by using the In other words: Installing and setting up VirtualenvInstalling virtualenv is easy. Debian provides a package for it
sa@wks:~$ type dpl; dpl virtualenv | grep ii
dpl is aliased to `dlocate -l'
ii python-virtualenv 1.4.9-1 Python virtual environment creator
sa@wks:~$ virtualenv --version
1.4.9
sa@wks:~$ virtualenv --help
Usage: virtualenv [OPTIONS] DEST_DIR
Options:
--version show program's version number and exit
-h, --help show this help message and exit
-v, --verbose Increase verbosity
-q, --quiet Decrease verbosity
-p PYTHON_EXE, --python=PYTHON_EXE
The Python interpreter to use, e.g.,
--python=python2.6 will use the python2.6
interpreter to create the new environment. The
default is the interpreter that virtualenv was
installed with (/usr/bin/python)
--clear Clear out the non-root install and start from
scratch
--no-site-packages Don't give access to the global site-packages dir
to the virtual environment
--unzip-setuptools Unzip Setuptools or Distribute when installing it
--relocatable Make an EXISTING virtualenv environment
relocatable. This fixes up scripts and makes all
.pth files relative
--distribute Use Distribute instead of Setuptools. Set environ
variableVIRTUALENV_USE_DISTRIBUTE to make it the
default
sa@wks:~$
Of course, one could also use Using VirtualenvBasically, what we need to know is how to create a new virtual environment (line 1), enter and activate it (lines 27 and 28), carry out some commands (e.g. line 29, looking what Python interpreter is currently active) and last but not least, switch back from the virtual environment into the global Python context/space (line 31) and yet again, look up the currently active Python interpreter (lines 32 and 33): 1 sa@wks:~/0/1$ virtualenv --distribute --no-site-packages my_test_virt_env 2 New python executable in my_test_virt_env/bin/python 3 Installing distribute................................done. 4 sa@wks:~/0/1$ type td; td my_test_virt_env/ 5 td is aliased to `tree --charset ascii -d -I \.git*\|*\.\~*\|*\.pyc' 6 my_test_virt_env/ 7 |-- bin 8 |-- include 9 | `-- python2.6 -> /usr/include/python2.6 10 `-- lib 11 `-- python2.6 12 |-- config -> /usr/lib/python2.6/config 13 |-- distutils 14 |-- encodings -> /usr/lib/python2.6/encodings 15 |-- lib-dynload -> /usr/lib/python2.6/lib-dynload 16 `-- site-packages 17 |-- distribute-0.6.10-py2.6.egg 18 | |-- EGG-INFO 19 | `-- setuptools 20 | |-- command 21 | `-- tests 22 `-- pip-0.8-py2.6.egg 23 `-- EGG-INFO 24 `-- scripts 25 26 18 directories 27 sa@wks:~/0/1$ cd my_test_virt_env/ 28 sa@wks:~/0/1/my_test_virt_env$ source bin/activate 29 (my_test_virt_env)sa@wks:~/0/1/my_test_virt_env$ which python 30 /home/sa/0/1/my_test_virt_env/bin/python 31 (my_test_virt_env)sa@wks:~/0/1/my_test_virt_env$ deactivate 32 sa@wks:~/0/1/my_test_virt_env$ which python 33 /usr/bin/python 34 sa@wks:~/0/1/my_test_virt_env$ cd The whole point of using VirtualenvwrapperVirtualenvwrapper is a set of extensions to virtualenv. The extensions include wrappers for creating and deleting virtual environments and otherwise managing our development workflow, making it easier to work on more than one project at a time without introducing conflicts in their dependencies. Installing and activating virtualenvwrapper is easy — one might
either use Next we are going to address our 35 sa@wks:~$ grep -A3 -m1 'WORKON_HOME .bashrc 36 export WORKON_HOME=$HOME/0/1 37 alias cdveroot='cd $WORKON_HOME' 38 sa@wks:~$ source .bashrc; echo $WORKON_HOME 39 /home/sa/0/1 The important part here is with line 36 where we tell virtualenvwrapper where our virtual environments are going to live on the filesystem. With line 37 we also add an alias which is going to save us a lot of
time down the road since it always beams us back into Excellent! We are done installing and setting up virtualenv and virtualenvwrapper. More information can be found here, here and here. Usage Examples - CommandsBelow I am going to provide a few examples about how to use virtualenvwrapper so folks can see how things work right away ;-] 40 sa@wks:~$ workon 41 my_test_virt_env 42 sa@wks:~$ workon my_test_virt_env 43 (my_test_virt_env)sa@wks:~$ cdvirtualenv 44 (my_test_virt_env)sa@wks:~/0/1/my_test_virt_env$ cdveroot 45 (my_test_virt_env)sa@wks:~/0/1$ ll 46 total 36K 47 drwxr-xr-x 6 sa sa 4.0K Dec 27 14:20 my_test_virt_env 48 -rwxr-xr-x 1 sa sa 67 Dec 27 15:27 postactivate 49 -rwxr-xr-x 1 sa sa 69 Dec 27 15:27 postdeactivate 50 -rwxr-xr-x 1 sa sa 67 Dec 27 15:27 postmkvirtualenv 51 -rwxr-xr-x 1 sa sa 61 Dec 27 15:27 postrmvirtualenv 52 -rwxr-xr-x 1 sa sa 68 Dec 27 15:27 preactivate 53 -rwxr-xr-x 1 sa sa 70 Dec 27 15:27 predeactivate 54 -rwxr-xr-x 1 sa sa 92 Dec 27 15:27 premkvirtualenv 55 -rwxr-xr-x 1 sa sa 62 Dec 27 15:27 prermvirtualenv 56 (my_test_virt_env)sa@wks:~/0/1$ cd /tmp 57 (my_test_virt_env)sa@wks:/tmp$ cdvirtualenv 58 (my_test_virt_env)sa@wks:~/0/1/my_test_virt_env$ pwd 59 /home/sa/0/1/my_test_virt_env The command reference list all commands available. My favorite is
probably 60 (my_test_virt_env)sa@wks:~/0/1/my_test_virt_env$ mkvirtualenv --no-site-packages --distribute test 61 New python executable in test/bin/python 62 Installing distribute.........................done. 63 (test)sa@wks:~/0/1/my_test_virt_env$ cdvirtualenv 64 (test)sa@wks:~/0/1/test$ workon 65 my_test_virt_env 66 test Line 60 shows how easy it is to create a new virtual environment using
Now we have two virtual environments (lines 65 and 66) already which
can be listed using
67 (test)sa@wks:~/0/1/test$ workon my_test_virt_env
68 (my_test_virt_env)sa@wks:~/0/1/test$ cdvirtualenv
69 (my_test_virt_env)sa@wks:~/0/1/my_test_virt_env$ rmvirtualenv my_test_virt_env
70 ERROR: You cannot remove the active environment ('my_test_virt_env').
71 Either switch to another environment, or run 'deactivate'.
72 (my_test_virt_env)sa@wks:~/0/1/my_test_virt_env$ rmvirtualenv test
73 (my_test_virt_env)sa@wks:~/0/1/my_test_virt_env$ workon
74 my_test_virt_env
Lines 67 to 74 show a few things about deleting a virtual environment.
As we can see from lines 69 to 71, deleting/removing the currently
active virtual environment does not work — this is a safety switch
provided by virtualenvwrapper. As lines 72 to 74 show, our former
created virtual environment 75 (my_test_virt_env)sa@wks:~/0/1/my_test_virt_env$ cd 76 (my_test_virt_env)sa@wks:~$ cdvirtualenv bin 77 (my_test_virt_env)sa@wks:~/0/1/my_test_virt_env/bin$ pwd 78 /home/sa/0/1/my_test_virt_env/bin 79 (my_test_virt_env)sa@wks:~/0/1/my_test_virt_env/bin$ 80 (my_test_virt_env)sa@wks:~/0/1/my_test_virt_env/bin$ cdsitepackages 81 (my_test_virt_env)sa@wks:~/0/1/my_test_virt_env/lib/python2.6/site-packages$ pwd 82 /home/sa/0/1/my_test_virt_env/lib/python2.6/site-packages Since I am such a fan of
83 (my_test_virt_env)sa@wks:~/0/1/my_test_virt_env/lib/python2.6/site-packages$ cd 84 (my_test_virt_env)sa@wks:~$ lssitepackages 85 distribute-0.6.10-py2.6.egg pip-0.8-py2.6.egg virtualenvwrapper 86 easy-install.pth setuptools.pth virtualenvwrapper-1.23-py2.6.egg-info 87 (my_test_virt_env)sa@wks:~$ lssitepackages -l 88 total 24 89 drwxr-xr-x 4 sa sa 4096 Dec 27 12:55 distribute-0.6.10-py2.6.egg 90 -rw-r--r-- 1 sa sa 236 Dec 27 12:55 easy-install.pth 91 drwxr-xr-x 3 sa sa 4096 Dec 27 12:55 pip-0.8-py2.6.egg 92 -rw-r--r-- 1 sa sa 29 Dec 27 12:55 setuptools.pth 93 drwxr-xr-x 3 sa sa 4096 Dec 27 14:30 virtualenvwrapper 94 drwxr-xr-x 2 sa sa 4096 Dec 27 14:30 virtualenvwrapper-1.23-py2.6.egg-info 95 (my_test_virt_env)sa@wks:~/0/1$ cd /tmp However, what if we just wanted to know its contents without visiting
The last command we are going to take a look at is 96 (my_test_virt_env)sa@wks:/tmp$ git clone git://github.com/pinax/pinax.git 97 Initialized empty Git repository in /tmp/pinax/.git/ 98 remote: Counting objects: 26080, done. 99 remote: Compressing objects: 100% (9391/9391), done. 100 remote: Total 26080 (delta 14937), reused 25917 (delta 14828) 101 Receiving objects: 100% (26080/26080), 13.43 MiB | 120 KiB/s, done. 102 Resolving deltas: 100% (14937/14937), done. 103 (my_test_virt_env)sa@wks:/tmp$ cdvirtualenv 104 (my_test_virt_env)sa@wks:~/0/1/my_test_virt_env$ python 105 Python 2.6.4 (r254:67916, Nov 19 2009, 22:14:20) 106 [GCC 4.3.4] on linux2 107 Type "help", "copyright", "credits" or "license" for more information. 108 >>> import sys, pprint 109 >>> pprint.pprint(sys.path) 110 ['', 111 '/home/sa/0/1/my_test_virt_env/lib/python2.6/site-packages/distribute-0.6.10-py2.6.egg', 112 '/home/sa/0/1/my_test_virt_env/lib/python2.6/site-packages/pip-0.8-py2.6.egg', 113 '/home/sa/0/1/my_test_virt_env/lib/python2.6', 114 '/home/sa/0/1/my_test_virt_env/lib/python2.6/plat-linux2', 115 '/home/sa/0/1/my_test_virt_env/lib/python2.6/lib-tk', 116 '/home/sa/0/1/my_test_virt_env/lib/python2.6/lib-dynload', 117 '/usr/lib/python2.6', 118 '/usr/lib64/python2.6', 119 '/usr/lib/python2.6/plat-linux2', 120 '/usr/lib/python2.6/lib-tk', 121 '/usr/lib64/python2.6/lib-tk', 122 '/home/sa/0/1/my_test_virt_env/lib/python2.6/site-packages'] 123 >>> 124 (my_test_virt_env)sa@wks:~/0/1/my_test_virt_env$ cdsitepackages 125 (my_test_virt_env)sa@wks:~/0/1/my_test_virt_env/lib/python2.6/site-packages$ type pi; pi pth 126 pi is aliased to `ls -la | grep' 127 -rw-r--r-- 1 sa sa 236 Dec 27 12:55 easy-install.pth 128 -rw-r--r-- 1 sa sa 29 Dec 27 12:55 setuptools.pth 129 (my_test_virt_env)sa@wks:~/0/1/my_test_virt_env/lib/python2.6/site-packages$ add2virtualenv /tmp/pinax/ 130 Warning: Converting "/tmp/pinax/" to "/tmp/pinax" 131 (my_test_virt_env)sa@wks:~/0/1/my_test_virt_env/lib/python2.6/site-packages$ pi pth 132 -rw-r--r-- 1 sa sa 236 Dec 27 12:55 easy-install.pth 133 -rw-r--r-- 1 sa sa 29 Dec 27 12:55 setuptools.pth 134 -rw-r--r-- 1 sa sa 11 Dec 27 22:46 virtualenv_path_extensions.pth 135 (my_test_virt_env)sa@wks:~/0/1/my_test_virt_env/lib/python2.6/site-packages$ cat virtualenv_path_extensions.pth 136 /tmp/pinax 137 (my_test_virt_env)sa@wks:~/0/1/my_test_virt_env/lib/python2.6/site-packages$ python 138 Python 2.6.4 (r254:67916, Nov 19 2009, 22:14:20) 139 [GCC 4.3.4] on linux2 140 Type "help", "copyright", "credits" or "license" for more information. 141 >>> import sys, pprint 142 >>> pprint.pprint(sys.path) 143 ['', 144 '/home/sa/0/1/my_test_virt_env/lib/python2.6/site-packages/distribute-0.6.10-py2.6.egg', 145 '/home/sa/0/1/my_test_virt_env/lib/python2.6/site-packages/pip-0.8-py2.6.egg', 146 '/home/sa/0/1/my_test_virt_env/lib/python2.6', 147 '/home/sa/0/1/my_test_virt_env/lib/python2.6/plat-linux2', 148 '/home/sa/0/1/my_test_virt_env/lib/python2.6/lib-tk', 149 '/home/sa/0/1/my_test_virt_env/lib/python2.6/lib-dynload', 150 '/usr/lib/python2.6', 151 '/usr/lib64/python2.6', 152 '/usr/lib/python2.6/plat-linux2', 153 '/usr/lib/python2.6/lib-tk', 154 '/usr/lib64/python2.6/lib-tk', 155 '/home/sa/0/1/my_test_virt_env/lib/python2.6/site-packages', 156 '/tmp/pinax'] 157 >>> 158 (my_test_virt_env)sa@wks:~/0/1/my_test_virt_env/lib/python2.6/site-packages$ cdvirtualenv 159 (my_test_virt_env)sa@wks:~/0/1/my_test_virt_env$ add2virtualenv 160 Usage: add2virtualenv dir [dir ...] 161 162 Existing paths: 163 /tmp/pinax 164 (my_test_virt_env) sa@wks:~/0/1/my_test_virt_env$ python -c 'import pinax; print pinax.VERSION' 165 (0, 9, 0, 'alpha', 1) 166 (my_test_virt_env) sa@wks:~/0/1/my_test_virt_env$ cd; deactivate With this example we first clone (read download) Pinax source code
into The important thing above is with line 129 which makes it so that
Usage Examples - HooksVirtualenvwrapper provides hooks that can be used to carry out actions at certain times depending on the work we do with regards to our virtual environments. There are two types of hooks. Global hooks (lines 48 to 55) which live
in Secondly, there are per virtual environment hooks which live in
While we have a bunch of global hooks, currently (August 2010) there
are only four per virtual environment hooks namely Hooks are either sourced (allowing them to modify our shell
environment e.g. change the color of our shell prompt) or run as an
external program (e.g. As an example, we are going to add a little color in order to make it easier for us to distinguish whether we are using a virtual environment or whether we are acting within the global Python context/space of our operating system. 167 sa@wks:~/0/1$ ll 168 total 36K 169 drwxr-xr-x 6 sa sa 4.0K Dec 27 14:20 my_test_virt_env 170 -rwxr-xr-x 1 sa sa 150 Dec 27 21:11 postactivate 171 -rwxr-xr-x 1 sa sa 69 Dec 27 15:27 postdeactivate 172 -rwxr-xr-x 1 sa sa 67 Dec 27 15:27 postmkvirtualenv 173 -rwxr-xr-x 1 sa sa 61 Dec 27 15:27 postrmvirtualenv 174 -rwxr-xr-x 1 sa sa 68 Dec 27 15:27 preactivate 175 -rwxr-xr-x 1 sa sa 70 Dec 27 15:27 predeactivate 176 -rwxr-xr-x 1 sa sa 92 Dec 27 15:27 premkvirtualenv 177 -rwxr-xr-x 1 sa sa 62 Dec 27 15:27 prermvirtualenv 178 sa@wks:~/0/1$ cat postactivate 179 #!/bin/sh 180 # This hook is run after every virtualenv is activated. 181 182 sa@wks:~/0/1$ workon my_test_virt_env 183 (my_test_virt_env)sa@wks:~/0/1$ tsw 184 (my_test_virt_env)sa@wks:~/0/1$ deactivate 185 sa@wks:~/0/1$ cat postactivate 186 #!/bin/sh 187 # This hook is run after every virtualenv is activated. 188 PS1="\[\033[01;33m\](`basename \"$VIRTUAL_ENV\"`)\[\033[00m\] $_OLD_VIRTUAL_PS1" 189 sa@wks:~/0/1$ workon my_test_virt_env 190 (my_test_virt_env) sa@wks:~/0/1/$ tsw 191 (my_test_virt_env) sa@wks:~/0/1/$ deactivate; cd 192 sa@wks:~$ The first image above show things before (read default virtualenv setting) line 188 was put into place. The second image shows things after we put line 188 in place — the currently active virtual environment is now yellow plus we got a blank in between the yellow colored virtual environment and our default prompt. The arcane Another very handy thing I would recommend putting into Since PIP is used by pretty much anybody these days, here is how we make virtualenv/virtualenvwrapper and PIP complement each other nicely, thus providing for enhanced user experience:
sa@wks:~$ grep -A5 '. pip' .bashrc
###_ . pip
export PIP_VIRTUALENV_BASE=$WORKON_HOME
export PIP_RESPECT_VIRTUALENV=true
export PIP_REQUIRE_VIRTUALENV=true
export VIRTUALENV_USE_DISTRIBUTE=1
sa@wks:~$
This makes PIP detect an active virtual environment and install to it,
without having to pass it the Also, Django EnvironmentThis one I love! So far we have seen how to create virtual environments. We even use virtualenvwrapper to make it a joy to work with those virtual environments. We create all kinds of Python projects atop/inside those virtual
environments e.g. we can test our code with different Python versions
like for example 2.7 and 3.2 by simply switching back and forth with
However, while creating virtual environments is now easy and fast
( Virtualenv-CommandsSo far I am not using it but from what I have seen it is pretty cool too. Please go here and here for more information. PIP
Bash CompletionIn order to have Bash completion with PIP, here is what we do:
sa@wks:~$ grep -A7 "^_pip_completion()" .bashrc
_pip_completion()
{
COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \
COMP_CWORD=$COMP_CWORD \
PIP_AUTO_COMPLETE=1 $1 ) )
}
complete -o default -F _pip_completion pip
sa@wks:~$
A quick Editable PackagesThose are packages/applications we install using Disutils / Setuptools / DistributeOne should have read about the history of packaging before continuing here.
DistributeThis is the one we recommend to use. It is the successor to Setuptools, which itself has always been considered the better Distutils.
Fabric
DebuggerChecker
Profiling
GNU EmacsSince GNU Emacs is my weapon of choice for pretty much any battle these days, I would like to honor my good fellow by explicitly telling a bit how I made the out of the box setup which Emacs provides for Python programming even more cosy ;-] MiscellaneousSecurityThis section is about handling security with special regards to how to do this in the Django and Pinax ecosystem. It will also touch on pure Python matters wherever needed and appropriate. The more general view towards security on a lower layer (operating system, network, storage, etc.) has its own page.
Anti-spam Measures
Authentication
MultimediaThis section is about handling multimedia with special regards to how to do this in the Django and Pinax ecosystem. It will however touch on pure Unix/Linux/Python matters wherever needed and appropriate. In short, with this section we are going to have a look at how to retrieve, process, store and serve all sorts of multimedia contents. AudioDynamic Images
Encodingsa@wks:~$ dpkg -l ffmpeg* | grep ii ii ffmpeg2theora 0.24-2+b1 Theora video encoder using ffmpeg sa@wks:~$ Static ImagesProject and Life-Cycle ManagementProject ManagementLife-Cycle ManagementSoftware Development TechniquesTest-driven DevelopmentTDD (Test-driven Development) |