There's strictly no warranty for the correctness of this text. You use any of the information provided here at your own risk.
Preface (2021): This is an old page about Python, I must have written in about 2008. Most information may still be valid though.
Today, there's a dispute about whether to use Python 3.x or Python 2.7. The most obvious change in Python 3 was, that "print" wasn't a command any more, but a function. So in Python 3 you always had to write brackets around things you wanted to print, like:
print("Hello")
As Python is a language that reduces the characters to write as much as possible (leaving out all the ";" and "{ ...} " found in other languages), many people found that change to "print" very annoying. They kept using Python 2.7. And so do I. So this page is about Python 2.7, and some code may need to be adapted, if it was to run on Python 3.x.
I hope, in Python 4 they make it possible again to write "print" without brackets. Or maybe allow the programmer to write it the way he or she wants (that is, with or without brackets).
Otherwise, Python 2.7 will still be the way to go.
Python is an interpreted programming language created by Guido van Rossum. It was first released in 1991.
The name "Python" referrs to the name of the comedy-group "Monty Python", not to the snake, but I use to ignore that, as I don't see such a big connection between the work of Monty Python and programming in general.
The Python-interpreter is freely available for Windows, Linux and Apple Mac OS-X.
If you run Linux or Mac OS-X, Python is probably already installed on your computer. Open a terminal, type "python" and you should be in its interactive mode (which you can leave with "CTRL+d" again).
With Python you can write small scripts doing just imperative programming as well as write large applications in a structured or in an object-orientated programming-style.
Python is designed to make things easy for the programmer. It provides flexible dynamic datatypes like lists and hashes (called "dictionaries") and takes care of memory management. It tries to come with
"Batteries included".
That means, a standard Python-distribution already has a lot of modules for many tasks, so there is a good chance, you can do what you want without searching and installing further modules and if you make your scripts available to other people, they can run them just like that.
But of course there are many very interesting modules that are not part of the Python-distribution too. A lot of those are listed here (a huge list, may take some time to load).
Python's syntax is as clear as possible, so its code is easy to read even years after writing.
This is achieved mainly by two unusual concepts:
1. In Python, everything is an object. Objects can have attributes and methods, so it is defined what can be done with them.
Therefore you don't have to declare variables, Python can read the variable-type from the context. For example if you do
a = 1
"a" becomes an object of type integer. You can verify this by doing:
print type(a)
So you don't have to write things like "int a = 1;" (like in C/C++) or even "my $a = 1;" (like in Perl) which makes code less readable.
2. In Python, code-indentation matters. Python reads the range of code blocks from the indentation-level:
for i in range(10): print i if i == 5: print "i is 5 now."
It's good coding style to use four space-characters for one indentation-level like in the example above.
Remember, readability matters!
So using Python, you don't need those ugly "{" and "}" like in C/C++, Java or Perl anymore.
While Perl's motto is "There's more than one way to do it." (TMTOWTDI), Python follows the concept of:
"There should be one -- and preferably only one -- obvious way to do it."
(Some of these concepts are shown as an easter-egg, if you do "import this" in Python's interactive mode.)
As the Python-interpreter is available for all three operating-systems mentioned above and most Python-functions can be called in a very general, high-level way, Python is very well suitable for writing platform-independent programs.
With Python you're not limited to writing text-only-console-programs. You can write GUI (= Window, point and click)-programs too. Bindings for many GUI-toolkits such as Tk, Gtk, wxWidgets, Qt, Windows-MFC and Apple-Cocoa are available. The Tk-module called "Tkinter" already comes with the Python-interpreter.
Besides the commonly used C-implementation of Python called CPython, which I mentioned above, there are also implementations in other languages. The Java-version is called Jython. With it (and the Java SDK), it is said to be possible to compile Python-code directly to Java-bytecode, that then can run on any Java Virtual Machine (but I haven't tested that yet.).
In general, Python is a high-level-programming-language (although you can accomplish surprisingly low-level-tasks with it too).
The code of a Python-program is 2-10 times shorter than the code of a comparable C/C++-program. It is much easier to understand too.
The price for that is, that C/C++ runs faster than Python.
Nevertheless, Python's speed is sufficient for a lot of tasks.
For example, Python-code may not be fast enough to render a 3D-shooter, but you can build a 3D-shooter with an engine written in C doing all the low-level-graphics-work and use Python to control that engine.
Executing a Python-script isn't difficult: Copy and paste its code into a text-editor.
On Windows, "Notepad.exe" will do, but you can also use an IDE ("Integrated Development Environment") like Pythonwin.
On Linux, I suggest learning how to use one of the editors "vim" or "emacs", but "kate", "gedit" or "kwrite" will do, too. There's also a nice IDE called Eric.
Make sure, that all characters are copied and pasted correctly and that all code-indentation is kept.
Then save the script as for example "script.py".
On Windows, you can then run the script by double-clicking it. If it's a GUI-application, you may want to get rid of the DOS-box that is usually opened. You can achieve this just by calling your script "script.pyw". In a DOS-box you can run your script by typing
python script.py
in its directory. On Linux, you have to make your script executable first. You can do that by executing
chmod +x script.pyAfter that you can run it by doing
./script.py
in its directory.
I won't teach you here the basics of Python-programming; there already are enough ressources about that on the internet.
I recommend reading some of these free online-books (listed from easy to more difficult to understand) :
It's also a good idea to buy at least one printed book on Python-programming.
Help on certain modules can be found using the "pydoc"-shell-command:
pydoc time
for example shows help about the "time"-module,
pydoc time.sleep
help about the "sleep"-method included in the "time"-module. There's also a "help()"-command in Python's interactive mode.
Now I would like to show some things, you can do with Python.
Python has an interactive mode. It appears, if you just execute
python
Although it is not its main-purpose, you can use this interactive mode as a calculator. You can type there for example:
print 42. * (87. - 32.4) / 3.4
There's just one thing, you have to take care of:
If you want to use integers like for example "42", you have to type them as float, that is with a point after them like "42.", which is short for "42.0". If you don't do that, you will probably get mathematically wrong results, because there are differences in the internal representations of the data-types "int" and "float" !
After doing
import mathyou can do even more advanced calculations there, for example:
print math.sin(45.)
or
print math.pow(2., 3.)
Please see "pydoc math" for details about the "math"-module.
This script demonstrates some often-used file-operations:
#!/usr/bin/python # coding: utf-8 import os import sys import glob # Get current working directory: PATH = os.getcwd() FILE = PATH + "/myfile.txt" # Test, if file exists: if os.access(FILE, os.F_OK): print "File already exists." sys.exit(1) fh = file(FILE, "w") fh.write("This is a line of text.\n") fh.write("This is another line.\n") fh.close() fh = file(FILE, "r") a = fh.readlines() fh.close() for i in a: print i.rstrip("\n") os.remove(FILE) print "The directory contains:" b = os.listdir(PATH) for i in b: print i # Filename globbing: print print "The directory contains the following html-files:" b = glob.glob("*html") if b: for i in b: print i else: print "None."
For copying and moving files and directories and for deleting directories recursively, it is recommended to use the module "shutil".
Just like that:
#!/usr/bin/python # coding: utf-8 import random random.seed() for i in range(10): print random.randrange(10)
The Python-module "re" provides support for powerful regular expression (like in Perl).
It seems, there are also the modules "re" and "pre".
In fact, you don't need the regular-expression-modules very often: Many find- and replace-operations can already be done with Python's builtin string-functions like
For simple find-operations, Python also offers an even more elegant and easy to use construction:
#!/usr/bin/python # coding: utf-8 mystring = "Hello World" if "World" in mystring: print '"World" found.'
This also works with lists and tuples.
Anyway, sometimes you can't avoid using regular expressions.
For these cases, the following script shows, how it can be done with the "re"-module (although some people use the similar module "re" instead):
#!/usr/bin/python # coding: utf-8 import re # First, we define the text to be used: text = "Text to be searched." # Then, we compile a "pattern-object" from a regular expression: patobj = re.compile("s.*") # Now we can do a search-operation on the text: matchobj = patobj.search(text) if matchobj is not None: print "Regular expression found in the text." # We can also extract the substring found in the search-operation: if matchobj is not None: print text[matchobj.start() : matchobj.end()] # Alternatively, this may work: print matchobj.group() # Additionaly, we can do replace-operations on the text: print re.sub(patobj, "replaced.", text) # Instead of the search- and replace-operations operations above, # you could also do: if re.search("s.*", text): print "Found." print re.sub("s.*", "replaced.", text) # But "re.compile()" is faster, if the regular expression is used # more than once.
If you want to extract html-tags from a html-file, there's a problem with greed. You should then use a regular expressions with its last character as a negated character-class:
#!/usr/bin/python # coding: utf-8 import re html = """<html> <body> <h2>Caption 1</h2> <p>Some text. <h2>Caption 2</h2> <p>Some more text. <br>Going on. </body> </html>""" html = html.split("\n") patobj = re.compile("<h2>([^>]*)<\/h2>") # Notice the regexp here. for line in html: line = line.rstrip("\n") matchobj = patobj.search(line) if matchobj: print matchobj.groups()[0]
The expression "<h2>([^>]*)<\/h2>" means:
'Find "<h2>", then any amount of characters, that aren't ">" (and mark them for extraction), then "</h2>".
The Tutorial says, you can also use "?" for marking an expression as being "not greedy" but the way above should be even more reliable.
The best practice to extract text from a HTML-page in Python, would be using the module "Beautiful Soup".
This script demonstrates some often-used operations concerning date and time (using the a little low-level time-module):
#!/usr/bin/python # coding: utf-8 import time # Print current time in central European format including seconds: print time.strftime("%H:%M:%S") # On Linux, you can read more about format-strings like "%H:%M:%S" # by executing the shell-command "info date". # Print today's date in central European format; the numbers of days and months # below 10 are zero-padded (like in 09.08.2007): print time.strftime("%d.%m.%Y") # Print seconds since epoch (on Linux, epoch is 1.1.1970): print time.time() # Generate a time-tuple from seconds since epoch and print it: tmtp = time.localtime(time.time()) print tmtp # Print today's date in central European format using the time-tuple generated above; # the numbers of days and months below 10 are blank-padded (like in 9.8.2007): print str(tmtp[2]) + "." + str(tmtp[1]) + "." + str(tmtp[0]) # Convert the time-tuple back to seconds since epoch: print time.mktime(tmtp)
If you want to calculate the time or the number of days between two or more dates, the datetime-module is even more useful:
#!/usr/bin/python # coding: utf-8 import datetime # Generate a datetime.date-object for today: d1 = datetime.date.today() print d1.strftime("%d.%m.%Y") # Generate a datetime.date-object for "30.01.2010": d2 = datetime.date(2010, 1, 30) # Now we can do some calculations with a datetime.timedelta-object: td = d1 - d2 a = "Today is " if d1 > d2: a += str(td.days) + " days after " else: a += str(td.days * -1) + " days before " a += d2.isoformat() + "." print a try: feb29 = datetime.date(d1.year, 2, 29) print "This year is a leap year." except ValueError: print "This year is not a leap year."
You can start other processes like that:
#!/usr/bin/python # coding: utf-8 import os os.system("ls")
If you want to grab the process' output, you can do:
#!/usr/bin/python # coding: utf-8 import os ph = os.popen("ls") a = ph.readlines() ph.close() print a
If you want to have more control over the started process, for example have it running for some time and pass commands to it while it's running, you should take a look at the Python-module
subprocess
On Microsoft Windows the command
os.startfile("somefile.html")
is very useful: It starts a file with its connected application (like clicking on its icon in "Explorer").
So in the example above, the system's default-browser is started showing "somefile.html".
That way, you don't have to worry about the application's correct start-command. Very nice.
"234".isdigit() Returns "True", if the string contains just numbers. More info: "pydoc __builtin__". chr(65), ord("A") These two functions convert an integer to an ASCII-code-string and back. The results here are "A" and 65. dir(object) Gives useful information about an object, especially about the names of its methods. list.remove("a") Removes the first element containing "a" from the list. Warning: If "remove()" is used while iterating over the list, the list and the loop get corrupted. In these cases always remove from a copy of the list instead. sys.argv A list, that holds the name of the Python-script and the arguments passed to it from the command line. time.sleep(0.5) Lets your Python sleep for half a second. This may not be useful in GUI-applications. For Tkinter please read "pydoc Tkinter.Tk" about "after" and "after_idle". type(object) Returns the type of an object; check with the special construction "if type(a) == str:", for example.
The following script shows, how these number-conversions can be done:
#!/usr/bin/python # coding: utf-8 hexnum = "FF"; decnum = 255; binnum = "11111111"; octnum = "377"; # Hexadecimal to decimal: print int(hexnum, 16) # Hexadecimal numbers start with "0x": print 0xFF # Decimal to hexadecimal: print hex(decnum) print "%X" % decnum # Binary to decimal: print int(binnum, 2) # Decimal to binary: print "{0:08b}".format(decnum) # Octal to decimal: print int(octnum, 8) # Octal numbers start with "0". # They are used for example in functions like os.chmod(). print 0377 # Decimal to octal: print oct(decnum) print "%o" % decnum
Notice, that the functions hex() and oct() return a string.
It seems, in earlier Python version (Python 2.4 and such) there wasn't built-in support for decimal-to-binary-conversion. A function "posdec2bin()" could have been used instead:
def posdec2bin(decnum): hexbin = {"0":"0000", "1":"0001", "2":"0010", "3":"0011", "4":"0100", "5":"0101", "6":"0110", "7":"0111", "8":"1000", "9":"1001", "A":"1010", "B":"1011", "C":"1100", "D":"1101", "E":"1110", "F":"1111"} hexnum = hex(decnum)[2:] hexnum = hexnum.upper() binlist = [] for i in hexnum: binlist.append(hexbin[i]) binstring = "".join(binlist) binstring = binstring.lstrip("0") return binstring
Modules often come with a "setup.py"-file. Usually, it should be run as root with
python setup.py install
Help on more commands "setup.py" knows, can be found doing
python setup.py --help-commands
When you execute a Python-script, bytecode is generated. Sometimes it is saved as a .pyc-files. These files can be executed by Python just like .py-files. They start a little faster too, but don't run faster. They don't contain plain-text, so they can't be viewed in an editor directly, but they can be retransformed to .py-files by using something like this.
However, if you want to generate a .pyc-file for a certain .py-file, you can use the script "compileall.py", that comes with your Python-distribution.
First, download these two modules and install them:
pycrypto
yawpycrypto and also its "Flatten"-module.
Then you should be able to run the following example-script:
#!/usr/bin/python # coding: utf-8 import os import sys import base64 from yawPyCrypto.Cipher import DecryptCipher, EncryptCipher from yawPyCrypto.Cipher import ZipDecryptCipher, ZipEncryptCipher from yawPyCrypto.Constants import CIPHER_BLOWFISH, MODE_CBC def doEncrypt(text, passw = None): e = EncryptCipher(passw, CIPHER_BLOWFISH, MODE_CBC) e.feed(text) e.finish() encryptedtext = e.data if passw != None: passwr = passw else: passwr = e.password a = (encryptedtext, passwr) return a def doDecrypt(encryptedtext, passw): d = DecryptCipher(passw) d.feed(encryptedtext) d.finish() decoded = (d.data) return decoded # Calling the encryption routine. # If you just pass the text to encrypt, a password is generated: a = doEncrypt("For your eyes only !", "Melina") # Just trying to clean the screen: if sys.platform == "win32": os.system("cls") else: os.system("clear") print print "Hello !" print print "I just encrypted some text. It looks like this now:" print print base64.b64encode(a[0]) print print 'Please notice, that I just encoded the text once more using "base64.b64encode()" to make it printable.' print print "The password for decryption is: " print print base64.b64encode(a[1]) print print "Let's decrypt again (the original password must be passed without b64encoding):" print print doDecrypt(a[0], a[1]) print
Sometimes, it's not necessary to use Python for such tasks. You can do encryption and decryption with programs like "gpg" too:
#!/bin/bash # Cleanup, if the script has been run before: a="unencrypted.txt encrypted.txt decrypted.txt" for i in $a do if test -f "$i" then rm "$i" fi done echo 'For your eyes only !' > unencrypted.txt # Encrypting to file 'encrypted.txt' using password "Melina": echo 'Melina' | gpg --batch --textmode --passphrase-fd 0 -o encrypted.txt -c unencrypted.txt # Decrypting to file 'decrypted.txt' using password "Melina": echo 'Melina' | gpg --batch --textmode --passphrase-fd 0 -d encrypted.txt > decrypted.txt
You can use Python as a scripting language for LibreOffice. To be able to do that, you have to do two things first:
1. There's a Python-module called "uno.py" that needs to be imported in the Python-script. "uno.py" comes with LibreOffice. It should be in its "program"-directory. You have to make sure, that it can be found by Python. This can be done by putting a file "uno.pth" into the python-path, for example to "/usr/lib/python/site-packages". The file "uno.pth" needs to contain just the path to the LibreOffice-"program"-directory, for example
/usr/lib/libreoffice/program
2. To accept python-scripting, LibreOffice needs to be activated in a special server-mode. This is done by starting it with
oowriter -accept="socket,host=localhost,port=2002;urp;"
If it's started this way, it accepts scripting from a script like this:
#!/usr/bin/python import uno from com.sun.star.text.ControlCharacter import PARAGRAPH_BREAK # Initializing: local = uno.getComponentContext() resolver = local.ServiceManager.createInstanceWithContext ("com.sun.star.bridge.UnoUrlResolver", local) context = resolver.resolve ("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext") desktop = context.ServiceManager.createInstanceWithContext ("com.sun.star.frame.Desktop", context) # Creating a new document: document = desktop.loadComponentFromURL( "private:factory/swriter", "_blank", 0, () ) # This would write into the current document instead, if one was already loaded: # document = desktop.getCurrentComponent() cursor = document.Text.createTextCursor() document.Text.insertString(cursor, "Hellow", 0) # Doing a "Backspace" deleting the "w" from "Hellow": cursor.goLeft(1,1) cursor.setString("") # Insert a "Return": document.Text.insertControlCharacter(cursor, PARAGRAPH_BREAK,0) document.Text.insertString(cursor, "Hello from Python.", 0) """ Other things (this part is currently not executed): Loading a new document would be: document = desktop.loadComponentFromURL("file:///home/user/letter.odt", "_blank", 0, () ) cursor = document.Text.createTextCursor() Going to an already existing Bookmark named "bmark" would be: Bookmark = document.Bookmarks.getByName(bmark) cursor = document.Text.createTextCursorByRange(Bookmark.Anchor) Inserting into an already existing TextFrame called "name" would be: frames=document.getTextFrames() frame=frames.getByName(name) cursor = frame.Text.createTextCursor() frame.Text.insertString(cursor, "Hello.", 0) """
The Pygame-modules provide Python-access to SDL, a multimedia-library comparable to MS DirectX.
Pygame gives you a window in which you can draw graphical objects, move them around and remove them again. It also provides modules for processing keyboard- and mouse-events and for playing several sounds and additionally music at the same time.
So, within certain speed-limits, you can use Pygame to program 2D-games. The games "SolarWolf" and "Barbie Seahorse Adventures" give an example of what is possible with Pygame.
To get sound working correctly with my soundcard, I have to do
export SDL_AUDIODRIVER=alsa
before starting a Pygame-application.
From time to time there are Pygame-programming-competitions at PyWeek. You can download a lot of interesting Pygame-games there.
Pygame's capabilities can also be used for other purposes than game-programming. Here is a script, that calculates some mathematical object and plots it to the screen. The picture is calculated and even plotted point by point, but the screen is only updated once, after calculation has been finished. Otherwise the script would run much slower. Press "q" to quit it:
#!/usr/bin/python # coding: utf-8 import pygame, sys,os import math from pygame.locals import * # Screen resolution: RESX = 800 RESY = 600 pygame.display.init() window = pygame.display.set_mode((RESX, RESY)) pygame.display.set_caption('Gauss') screen = pygame.display.get_surface() b = 0.3 ULIM = 100. UDIV = 1.8 for u in range(0, int(ULIM), 1): # Some mathematical, Gaussian calculations: a = float(u) / (ULIM / UDIV) if u > ULIM / 2: a = UDIV - (float(u) / (ULIM / UDIV)) m = u / 16. for x in range(50, RESX - 50): c = x / (RESX / 16.) - 5. y = a * math.exp(-b * (c - m) * (c - m)) # down: y = RESY / 10 + (y * RESY / 1.5 + u * 3) # up: # y = RESY * 9 / 10 - (y * RESY / 1.5 + u * 3) pygame.draw.line(screen, (200,200,200), (x, y), (x, y), 1) pygame.display.update() def input(events): for event in events: if event.type == QUIT: sys.exit(0) if event.dict.has_key('key') and event.dict['key'] == K_q: sys.exit(0) while True: input(pygame.event.get())
MySQL is a free database-system written in C/C++. It is included in most modern Linux-distributions. With it you can setup a powerful database-server, make it start at system-startup, create databases with lots of tables, populate those tables with data, search for that data and so on.
The MySQL-server is fast, and you can store millions of records in its databases.
You talk to it using the database-language SQL ("Structured Query Language").
Please notice, that MySQL uses its own user "root", who is different from the "root" of the Linux-system.
With the module mysql-python you can access MySQL-databases from Python. Probably you don't have to download the module. On SuSE-Linux 10 for example it can be found in the package "python-mysql....rpm". A small tutorial how to use the module can be found here.
The following example requires, that a MySQL-server has been set up and started. It also requires, that a MySQL-database "lang" with password "MyPassword" for user "root" and inside the database a table "languages" has been created and filled with some data. If the server is running and "root"'s password is "MyPassword", you can create and populate the database and its table automatically by saving the following SQL-code as "langs.mysql":
# langs.mysql: Just some example data. DROP DATABASE IF EXISTS `lang`; CREATE DATABASE `lang`; USE `lang`; DROP TABLE IF EXISTS `languages`; CREATE TABLE `languages` ( `Nr` int(11) NOT NULL default '0', `Name` varchar(30) NOT NULL default '', `LearnDate` date NOT NULL default '0000-00-00', `Impression` varchar(50) NOT NULL default '', `Score` decimal(9,2) NOT NULL default '0.00', PRIMARY KEY (`Nr`) ) TYPE=MyISAM; INSERT INTO `languages` (`Nr`, `Name`, `LearnDate`, `Impression`, `Score`) VALUES (1, 'C', '2001-01-01', 'Fast, but difficult.', '2.00'); INSERT INTO `languages` (`Nr`, `Name`, `LearnDate`, `Impression`, `Score`) VALUES (2, 'Perl', '2002-03-25', 'Nice, but terse syntax.', '2.50'); INSERT INTO `languages` (`Nr`, `Name`, `LearnDate`, `Impression`, `Score`) VALUES (3, 'Python', '2004-05-01', 'Clean syntax, flexible.', '3.00');
Then run this command on it (Warning: If a database "lang" already exists on the MySQL-server, it is deleted without warning):
mysql -u root -pMyPassword < langs.mysql
With the module mentioned above, this Python-script accesses the table "languages" in the database "lang" and prints each of its records as a tuple:
#!/usr/bin/python # coding: utf-8 import MySQLdb conn = MySQLdb.connect(host = "localhost", user = "root", passwd = "MyPassword", db = "lang") cursor = conn.cursor() cursor.execute("SELECT * FROM languages") while 1: row = cursor.fetchone() if row == None: break print row cursor.close() conn.close()
Tkinter is one of the GUI-toolkits available for Python. With it, you can create window-applications.
Actually Tkinter is an interface to Tk, the GUI-toolkit of the language "Tcl", but usually you won't notice that.
Tkinter is quite small in relation to other GUI-toolkits. That's why it comes with the Python-interpreter, although its windows don't look too beautiful.
The following script "msgbox.py" provides a simple messagebox in Tkinter. You can use it on Linux for example if you have difficulties with the font-size of Xdialog:
#!/usr/bin/python # coding: utf-8 # msgbox.py import os import Tkinter as tk class MyMsgBox: def __init__(self, title = "My Title", msg = "Some text"): if os.name == "nt": self.appfont = "{Arial} 10 {normal}" elif os.name == "posix": self.appfont = "{suse sans} 15 {normal}" else: self.appfont = "{suse sans} 15 {normal}" self.mw = tk.Tk() self.mw.title(title) # self.mw.iconname(iconname) self.mw.geometry("+350+300") self.mw.option_add("*font", self.appfont) self.label = tk.Label(self.mw, text = msg) self.label.pack(side = tk.TOP, anchor = tk.W, padx = 50, pady = 10) self.btn_exit = tk.Button(self.mw, text = "Ok", command = self.mw.destroy) self.btn_exit.focus() self.btn_exit.bind('<Return>', self.mwDestroy) self.btn_exit.pack(side = tk.RIGHT, anchor = tk.E, padx = 20, pady = 15) self.mw.mainloop() def mwDestroy(self, a): self.mw.destroy() if __name__ == "__main__": app = MyMsgBox("Hello", "Some text.")
You can run "msgbox.py" directly, but in general it is meant to be used as a module that is called from another script:
#!/usr/bin/python # coding: utf-8 from msgbox import MyMsgBox msgb = MyMsgBox("Window", "Hello from the controlling script.")
If you have already an opened Toplevel-tkinter-window, you can even do this instead:
#!/usr/bin/python # coding: utf-8 import tkMessageBox tkMessageBox.showinfo(title = "Hello", message = "Some text")
With Python you can parse configuration-files using the module "ConfigParser", which is part of the Python-distribution.
The configuration-files have to be in a standard-format: They must have sections, followed by options and values in a format like this:
[section] option=value option=valueTake for example the configuration-file for the KDE-editor "kate" called "katerc". If "kate" is installed, it can be found here:
/home/user/.kde/share/config/katerc
If your "katerc" looks like this:
[$Version] update_info=kate-2.4.upd:kate2.4 [Filelist] Edit Shade=255,102,153 Shading Enabled=true Sort Type=0 View Shade=51,204,255 [General] Days Meta Infos=30 Modified Notification=false
you can use the following Python-script in its directory to parse it:
#!/usr/bin/python # coding: utf-8 import ConfigParser c = ConfigParser.ConfigParser() # Read in the configuration in file "katerc": c.read("katerc") secs = c.sections() print print "These are all sections, options and values:" print for i in secs: print i opts = c.options(i) for u in opts: value = c.get(i, u) print "\t" + u + "\t\t\t" + value print # Setting all values to "MyValue": for i in secs: opts = c.options(i) for u in opts: c.set(i, u, "MyValue") # Uncommenting the following lines would write the configuration # stored in object "c" to a file "out.conf": # # FH = file("out.conf", "w") # c.write(FH) # FH.close() # print "New configuration written to file 'out.conf'."
Please see "pydoc ConfigParser" for further information.
For creating new PDFs using Python, I suggest the open-source-version of the "ReportLab" module-library.
With it, you can for example create a simple "Hello World"-pdf named "hello.pdf" like that:
#!/usr/bin/python # coding: utf-8 from reportlab.pdfgen import canvas c = canvas.Canvas("hello.pdf") c.drawString(100, 100, "Hello World") c.showPage() c.save()
For postprocessing already existing PDFs, I suggest using the "pyPDF"-module. It can
There's also ReportLab's "Pagecatcher" to do such things even more professionally, but it's not free.
Python comes with everything that is needed to establish an email-client without the help of other programs.
Modules included are "smtplib" and "email".
Sending emails is very easy with the script "simplemail.py", which is a wrapper around the modules mentioned above. With it you can send email just like that:
#!/usr/bin/python # coding: utf-8 from simplemail import Email Email(from_address = "sender@someadress.com", to_address = "receiver@someotheradress.com", subject = "Some subject.", message = "This is the message's text." ).send()
Email's data-format was originally meant for transmitting just plain text.
So all data, even of attachments like .jpg- or .mp3-files, is encoded and put together into a single text-message.
Such a message has headers beginning with "To:" or "Date:", followed by the email's text and so on.
So after receiving an email-message from a server, you have to parse it into the parts you're interested in.
You can do this with the module "email.Message".
The following script accesses a POP3-email-server "pop3.exampleserver.com", fetches all emails for user "user@exampleserver.com" there using password "examplepassword" and stores all email-parts including attachments in a handy Python-list. The script just prints this list, but of course you can do much more interesting things with it like for example extract only the messages' texts or save the attachments.
As you can see, element four of the list is the attachment stored as another list with just two elements, the attachment-filename and the attachment-data. The later can be saved using "fp = file(filename, "wb")" and proceeding as described above in "File-operations":
#!/usr/bin/python # coding: utf-8 import sys import poplib import email from email.Message import Message HOST = "pop3.exampleserver.com" USER = "user@exampleserver.com" PASSWORD = "examplepassword" def getAllEmails(host, user, passw): try: M = poplib.POP3(host) except: print "Error: Email-server not found." sys.exit(1) try: M.user(user) M.pass_(passw) except: print "Error loging in: Maybe invalid username or password." sys.exit(2) emails = [] maillist = M.list()[1] if len(maillist) > 0: for mailnr in range(len(maillist)): adress = "" subject = "" content = "" attachment = [] m = email.message_from_string("\n".join(M.retr(mailnr + 1)[1])) types = m.items() for a in types: if a[0] == "From": adress = a[1] if a[0] == "Subject": subject = a[1] for part in m.walk(): if part.get_content_maintype() == 'multipart': continue if part.get_content_maintype() == "text": content = part.get_payload(decode = True) if part.get_filename() is not None: attachment.append([part.get_filename(), part.get_payload(decode = True)]) emails.append([mailnr + 1, adress, subject, content, attachment]) M.quit() return emails a = getAllEmails(HOST, USER, PASSWORD) print a
It is also possible to delete emails directly on the distant server using "poplib.dele()".
It's amazing, that it's possible to set up a small html-server with just a few lines of Python-code:
#!/usr/bin/python # coding: utf-8 # httpd.py import sys from BaseHTTPServer import HTTPServer from CGIHTTPServer import CGIHTTPRequestHandler serveradresse = ("", 8080) server = HTTPServer(serveradresse, CGIHTTPRequestHandler) try: print print "Serving:" print "Please open a browser and point it to \"http://localhost:8080/test.html\"" print "Press \"CTRL+c\" to exit." server.serve_forever() except KeyboardInterrupt: print "Bye." sys.exit
It can manage .html-files found in and below its directory.
For example, you can put a file "test.html" there and access it with an internet-browser pointing to "http://localhost:8080/test.html".
If you just go to "http://localhost:8080/", the server tries to show you a page "index.html" in its directory.
You can also use the server to test your CGI-scripts.
Right now, I don't know how to make this small server part of the internet.
I doubt that it can handle too many accesses at once. For larger tasks I suggest using something like "Apache".
Writing Python-window (GUI)-applications using Tkinter is an interesting, but more complex subject.
Therefore, I've written another page about that, that can be found here.
Especially on Windows, many users seem to be reluctant to install the Python interpreter. They are used to computer programs coming as Windows executables, that is as ".exe"-files. Not as scripts with the file extensions ".py" or ".pyw", that look unfamiliar to them.
However, it is possible, to pack the parts of the Python interpreter and all the modules needed by a script to run, into a single ".exe"-file. That way, the script can also be handed out to users, that couldn't cope with installing the Python interpreter or even additional modules.
A program to create such a Windows executable is PyInstaller. To turn a GUI-script into a single ".exe"-file, it would be run like this:
pyinstaller --onefile --windowed yourscript.pyw
More options of PyInstaller can be found here.
Another way to create such an ".exe"-file would be py2exe. As it's an extension to the "distutils"-package, it has to be used a bit differently.
First, a file called "setup.py" has to be created, which holds all the options and points to your Python script. "setup.py" may look like this:
# setup.py from distutils.core import setup import py2exe, sys, os sys.argv.append('py2exe') setup( options = {'py2exe': {'bundle_files': 1, 'compressed': True}}, windows = [{'script': "yourscript.pyw"}], zipfile = None, )
Then, this command is run to create the ".exe"-file:
python setup.py py2exe
By default (with a simpler "setup.py"-file) py2exe creates a large directory with a much smaller ".exe"-file and all the library-files needed to run it.
More options of py2exe's "setup.py"-file can be found here.
The encoding-line at the beginning of a script tells the script, which encoding the script uses:
# coding: utf-8
for UTF-8 or
# coding: iso-8859-1
for ISO-8859-1 (= Latin 1).
Sometimes, there can be problems with encodings, when you try to ouput text, either to the console or to GUIs (like Tkinter). I suggest, experimenting with "str.decode()" or "str.encode()" then. Often, 'str.decode("iso-8859-1")' helps:
#!/usr/bin/python # coding: iso-8859-1 a = "Zwölf Boxkämpfer jagen Eva quer über den großen Sylter Deich." print a.decode("iso-8859-1")
On Linux, the result depends on the system locales, printed by the "locale"-command, like for example "$LANG". "$XTERM_LOCALE" may be another variable to look for.
Usually you don't have to write Python-modules in C, because you can just "import" every Python-script as a module into another script.
But it's interesting to see, that it is possible to mix Python and fast C-code. So here's an example (according to an article in "Linux-Magazin" from 2002):
There will be three small files: "gcd.c", "mymod.c" and "setup.py".
"gcd.c" contains a C-function we want to call from Python.
"mymod.c" and "setup.py" are needed to build the module. "mymod.c" describes the contents of "gcd.c" to the build-routine. It's a problem to make the datatypes of Python and C accessible from the other language.
This is "gcd.c":
/* gcd.c */ int gcd(int x, int y) { int g = y; while (x > 0) { g = x; x = y % x; y = g; } return g; }
Here comes "mymod.c":
#include <Python.h> extern int gcd(int, int); /* mymod.c */ /* Wrapper-functions for gcd() */ static PyObject* wrap_gcd(PyObject* self, PyObject* args) { int a, b, res; if (!PyArg_ParseTuple(args, "ii", &a, &b)) { return 0; } res = gcd(a, b); return Py_BuildValue("i", res); } /* Listing of all module-functions */ static PyMethodDef mymodMethods[] = { { "gcd", wrap_gcd, METH_VARARGS }, { 0 } }; /* Function is called when doing "import mymod". */ void initmymod() { Py_InitModule("mymod", mymodMethods); }
This is "setup.py":
#!/usr/bin/python # coding: utf-8 # setup.py from distutils.core import setup, Extension setup(name = "mymod", version = "0.01", maintainer = "whoever", ext_modules = [Extension('mymod', sources=['mymod.c', 'gcd.c'])] )
Now put these three files into a directory, then do
chmod +x setup.pyand after that
./setup.py build
A subdirectory "build" should have been created (the C-compiler "gcc" needs to be installed for this). Somewhere in the subdirectory a file "mymod.so" should be found. That's your new Python-module. Now you can do in its directory:
#!/usr/bin/python # coding: utf-8 import mymod print mymod.gcd(40, 8)
and should get a result of "8".
More on this topic here.