Python-announce-list
Threads by month
- ----- 2024 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2000 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1999 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
August 2003
- 59 participants
- 81 discussions
Soprano is a GUI app that scans a selected range of ip addresses and try to
get info about the hosts such as users, localgroups, shares, operating
system.
This program only runs under windows.
changes 0.002 > 0.003:.
added settings window
setting are saved in xml and are stored under data\setting.xml
setting include:
"logon as" with username and password or use null request
resolv hostname
shares
users
groups
info
portscanner
improved right click menu\submenu
new functions:
add user
add group
add share
send msg (NetMessageBufferSend)
Source code and windows binary at
http://sourceforge.net/projects/soprano/
1
0
python-dev Summary for 2003-08-01 through 2003-08-15
++++++++++++++++++++++++++++++++++++++++++++++++++++
This is a summary of traffic on the `python-dev mailing list`_ from
August 1, 2003 through August 15, 2003. It is intended to inform the
wider Python community of on-going developments on the list. To comment
on anything mentioned here, just post to python-list(a)python.org or
`comp.lang.python`_ with a subject line mentioning what you are
discussing. All python-dev members are interested in seeing ideas
discussed by the community, so don't hesitate to take a stance on
something. And if all of this really interests you then get involved
and join `python-dev`_!
This is the twenty-third summary written by Brett Cannon (about to move
for the umpteenth time).
All summaries are archived at http://www.python.org/dev/summary/ .
Please note that this summary is written using reStructuredText_ which
can be found at http://docutils.sf.net/rst.html . Any unfamiliar
punctuation is probably markup for reST_ (otherwise it is probably
regular expression syntax or a typo =); you can safely ignore it,
although I suggest learning reST; its simple and is accepted for `PEP
markup`_ and gives some perks for the HTML output. Also, because of the
wonders of programs that like to reformat text, I cannot guarantee you
will be able to run the text version of this summary through Docutils_
as-is unless it is from the original text file.
.. _PEP Markup: http://www.python.org/peps/pep-0012.html
The in-development version of the documentation for Python can be found
at http://www.python.org/dev/doc/devel/ and should be used when looking
up any documentation on something mentioned here. Python PEPs (Python
Enhancement Proposals) are located at http://www.python.org/peps/ . To
view files in the Python CVS online, go to
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/python/ .
.. _python-dev: http://www.python.org/dev/
.. _python-dev mailing list:
http://mail.python.org/mailman/listinfo/python-dev
.. _comp.lang.python: http://groups.google.com/groups?q=comp.lang.python
.. _Docutils: http://docutils.sf.net/
.. _reST:
.. _reStructuredText: http://docutils.sf.net/rst.html
.. contents::
.. _last summary:
http://www.python.org/dev/summary/2003-07-01_2003-07-31.html
=====================
Summary Announcements
=====================
Well, Michael Chermside responded to my question from the last summary
about whether the new format and style of the Summaries was good. Once
again a single person has led to how the summaries will be handled. You
guys need to speak up (although I like the side that won this time =)!
I am playing with layout once again. This time I am changing how the
"contributing threads" lists are formatted. I know some of you hate
inlined links in reST markup, but when these lists become huge it
becomes really hard to keep track of the URIs when I have to list them
away from the actual item on a separate line below the list of thread names.
With `Python 2.3` out the door bug reports have started to come in.
Work on 2.3.1 has begun. Please keep running the regression tests
(easiest way is to run either ``make test`` or run regrtest.py in the
test package; see the docs for the test package for help).
On a personal note, if anyone knows of any Python users and such in the
San Luis Obispo area of California, drop me a line at brett at python.org.
=========
Summaries
=========
-----------------------------------------
Python user helping Parrot? Treacherous!
-----------------------------------------
Michal Wallace decided to get AM Kuchling's `previous work
<http://www.amk.ca/conceit/parrot.html>`__ on getting Python code to run
on the Parrot_ virtual machine (which is what Perl 6 will use). Well,
the rather nutty fellow managed to get pretty damn far with it as shown
at http://pirate.versionhost.com/viewcvs.cgi/pirate/ . Michal was
actually almost done with handling pure Python code and was getting
ready to try to figure out how to get Parrot to handle C extension
modules with that being the biggest sticking point.
Since Parrot is not Python it does not have a parser for Python code;
problem if your code has an exec statement. This turned out to not be a
worry, though, since there are pure Python parsers out there.
All of this has direct relevance to python-dev because of the bet
between Guido and Dan Sugalski, developer of Parrot. The rules are
outlined at http://www.sidhe.org/~dan/blog/archives/2003_07.html#000219
. What is going to happen at OSCON 2004 is a benchmark program written
in pure Python will be run using a CVS checkout of Python against a
Parrot (after converting the bytecode to Parrot's own bytecode)
checkout; slowest implementation's author gets a pie in the face, buy
the winner's dev team a round of beer, and $10.
So why have this bet? This was discussed and basically came down to
finding out whether Parrot really can run Python fast. Parrot wants to
be the VM for as many languages as possible, including Python. This
acts as a way to motivate people to see how feasible this is.
And don't think that the CPython interpreter will disappear if Parrot
wins. Dan pointed out that even if he did win the bet that Guido would
probably want to keep CPython around since that is under his control and
allows testing out new language features much easier then having to deal
with Parrot and an external dev team. In other words, let other people
worry about forcing a Python-shaped peg into a Parrot-sized hole.
.. _Parrot: http://www.parrotcode.org/
Contributing threads:
* `pirate (python+parrot)
<http://mail.python.org/pipermail/python-dev/2003-August/037407.html>`__
----------------------------------------------------
python-mode gets its own SF project; Vim users laugh
----------------------------------------------------
Barry Warsaw, citing lack of time to "properly maintain python-mode.el",
has created a SourceForge project for the Emacs mode at
http://sf.net/projects/python-mode . This means all bug reports,
patches, etc. should be done at that project.
Martin v. Löwis suggested removing `python-mode.el`_ from Python itself
and to get it distributed with Emacs_ and XEmacs_. This way there does
not have to be any synchronization between the new SF project and the
Python CVS tree. As of right now, though, python-mode.el is still in
the Python CVS.
And to give equal billing to Vim_, my code editor of choice, since it
does not get as much coverage on python-dev as XEmacs does, here are
some scripts you might want to check out:
taglist.vim : http://vim.sourceforge.net/scripts/script.php?script_id=273
"provides an overview of the structure of source code files" by
splitting the window.
python_fold.vim :
http://vim.sourceforge.net/scripts/script.php?script_id=515
"This script uses the expr fold-method to create folds for python
source code."
vimDebug : http://vim.sourceforge.net/scripts/script.php?script_id=663
" integrates your favorite debugger with vim."
.. _python-mode.el: http://sf.net/projects/python-mode
.. _Emacs: http://www.gnu.org/software/emacs/emacs.html
.. _XEmacs: http://www.xemacs.org/
.. _Vim: http://www.vim.org/
Contributing threads:
* `New python-mode project at SourceForge
<http://mail.python.org/pipermail/python-dev/2003-August/037410.html>`__
* New place for python-mode bug reports and patches
<http://mail.python.org/pipermail/python-dev/2003-August/037451.html>`__
--------------------
Caching tuple hashes
--------------------
Raymond Hettinger asked if there was any reason why tuples, being
immutable, didn't cache their hash values. Strings cache their hashes
and they are immutable, so it seem to make sense.
It was pointed out, though, that tuples could contain an object that
changed its hash value between hash calls. Guido said, though, that it
was the responsibility of the object and not tuples to worry about
keeping a consistent hash value.
Guido also explained why strings cache their hashes. It turns out that
since strings are used so often for keys in dicts that caching their
hashes gave a large performance boost for almost any program, so the
effort was felt justified. But Guido did not see this same
justification for tuples. Thus tuples will not cache their hash values.
Contributing threads:
* `Caching tuple hashes
<http://mail.python.org/pipermail/python-dev/2003-August/037416.html>`__
-------------------------------
PyCon 2004 is under development
-------------------------------
Preparation for PyCon_ 2004 have now begun. With us getting the ball
rolling much earlier this conference should turn out to be even better
than last year (which, in my opinion, was great)! You can go to
http://www.python.org/pycon/dc2004/ to find links to lists to get
involved in organizing or just to be kept abreast of new developments.
.. _PyCon: http://www.python.org/pycon/dc2004/
Contributing threads:
* `PyCon DC 2004 Kickoff!
<http://mail.python.org/pipermail/python-dev/2003-August/037437.html>`__
----------------------------
Let the fixing of 2.3 begin!
----------------------------
The maintenance branch of Python 2.3 (named release23-maint) has been
created in CVS. Several bugs have already been fixed. For instructions
on how to check out a copy of the branch, read
http://www.python.org/dev/devfaq.html#c10 .
Contributing threads:
* `Python 2.3 maintenance branch is now open
<http://mail.python.org/pipermail/python-dev/2003-August/037440.html>`__
------------------------------------
When a void doesn't equal an integer
------------------------------------
After clearing up the confusing issue of the difference between a Python
int and a Python Integer (the former is <type 'int'> while the latter is
the union of <type 'int'> and <type 'long'> which is what Python is
moving towards so that the distinction practically disappears), the
discussion of how to handle a quirk of Win64 commenced. It turns out
that Win64 thinks that ``sizeof(void *) > sizeof(long)`` is a reasonable
thing to do. Well, all other platforms now and most likely for the rest
of Tim Peter's life (at least according to Tim's guess) don't and won't
hold this to be true.
As of right now Python claims that a void pointer can be held in a
Python int, but Win64 breaks that claim. Do we muck around with
Python's internals for this one strange exception that does not make
sense, such as making Python ints use long long? No, of course not.
Code would break, let alone the added complexity. So the needed changes
to the failing tests were dealt with and all seems to be fine with the
world again ... well, Win64 is still thinking on crack, but that is
someone else's problem.
Contributing threads:
* `sizeof(long) != sizeof(void*)
<http://mail.python.org/pipermail/python-dev/2003-August/037465.html>`__
------------------------------------
Where do I put all of my packages?!?
------------------------------------
As it stands now there are four places where packages can reside:
1. standard library
2. site-packages
3. site-python (on UNIX this is the same directory where your python2.3
directory exists)
4. PYTHONPATH environment variable
It was pointed out that this does not necessarily give one all the
options one might want. The above covers the Python core easily, but
there is not clear distinction for vendor packages, network-installed
packages, system-wide packages or user-installed packages; they are
covered by 2-4 above. The suggestion was to make more distinct places
available for installation and to make distutils aware of them.
A good way to see how this would be useful is to look at how OS X's
Panther will handle Python 2.3 . It will have the standard library in
the standard location of /usr/local/python2.4 . In that directory, the
site-packages directory is a symlink to a more system-aware location.
This is fine but what about a sysadmin who would rather avoid the
possibility of breaking OS X by messing with the OS's Python
installation? What about a user on that system who does not have root
but wants to have their own place to put their packages? There is
definitely room for adding more standard path locations for package
installations.
A PEP was being mentioned but appears to not have been written yet.
Contributing threads:
* `Multiple levels of site-packages
<http://mail.python.org/pipermail/python-dev/2003-August/037487.html>`__
-------------------------
Be careful with __slots__
-------------------------
Raymond Hettinger observed that using __slots__ or overriding
__getattribute__ fails silently when mistakenly used with old-style
classes. This has bitten him and others in the bum so he wanted to add
warning/error messages. Guido recommended passing on the warnings
because 1) those are "expert use only" tools, 2) PyChecker can already
detect the issue, and 3) there are other new-style/classic issues cannot
as readily be flagged.
It should be known that "__slots__ is a terrible hack with nasty,
hard-to-fathom side effects that should only be used by programmers at
grandmaster and wizard levels". So only use __slots__ if you can apply
the label of "programmer at grandmaster or wizard level" to yourself
without your programming peers laughting their bums off; you have been
warned.
Contributing threads:
* `Make it an error to use __slots__ with classic classes
<http://mail.python.org/pipermail/python-dev/2003-August/037537.html>`__
--------------
Plugging leaks
--------------
Michael Hudson thought he had discovered a leak somewhere and went off
on a little hunt. It turned out to be a red herring more or less, but
there was some discussion on the best way to find leaks through
regression tests.
The basic scheme that everyone seemed to use was to run the regression
test once to get any caching out of the way and then run the test a set
number of times and see if the reference counts seemed to grow. Michael
Hudson posted a diff to add such a testing feature to test/regrtest.py
at http://mail.python.org/pipermail/python-dev/2003-August/037617.html .
Tim Peters also posted a link to Zope's test driver at
http://cvs.zope.org/Zope3/test.py which includes a class named TrackRefs
which can help keep track of the leaked references as well as leaked
objects.
Contributing threads:
* `CALL_ATTR patch
<http://mail.python.org/pipermail/python-dev/2003-August/037485.html>`__
* `refleak hunting fun!
<http://mail.python.org/pipermail/python-dev/2003-August/037617.html>`__
-----------------------------------------
Making the interpreter its own executable
-----------------------------------------
As it stands now the Python interpreter is distributed as a bunch of
files mostly made up of the standard library. But wouldn't it be nice
if you could make the interpreter just a single executable that was easy
to distribute with your code? Well, that discussion cropped up on
`comp.lang.python`_ at
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&safe=off&threadm=ptji8wg…
. The idea was to somehow introduce a hook into Py_Main() that could
harness the new zipimport facility.
The idea came up of appending the stdlib to the end of the Python
interpreter and to have a flag set to signal that the appending had
occurred. The problem is that this could cause unzipping problems.
But setting the flag is not necessarily simple either. One suggestion
was to literally patch the interpreter to set the flag. But there was
some confusion over the use of the term "patch"; Thomas Heller thought
more of "link with an object file defining this global variable".
This thread was still going as of this writing and had not yet reached a
clear solution.
Contributing threads:
* `hook for standalone executable
<http://mail.python.org/pipermail/python-dev/2003-August/037528.html>`__
1
0
============================================================================
Python 2.3 for RISC OS release 2003-08-03
============================================================================
I'm pleased to announce that binaries of Python 2.3 for RISC OS are
available from http://www.schwertberger.de/python.html .
RISC OS Python includes the following highlights:
* An integrated interface to the SWI system
* Drawfile support
* Interfaces to the RISC OS WIMP and toolbox (with examples)
* Numeric extension
* PeerBoard: share your clipboard contents between multiple RISC OS
and win32 computers over TCP/IP connections
* SSLRelay: a simple SSL proxy server
For use of Python you will need a filing system with long filename and >77
files/directory support.
Bug reports etc.
================
RISC OS specific bug reports, contributions, comments, critics, links to
RISC OS compatible Python libraries to dietmar(a)schwertberger.de
1
0
=================================================
SC-Track Roundup 0.6.0 - an issue tracking system
=================================================
I'm pleased to announce the latest feature-packed release of Roundup. See
below for a list of some of the goodies included in this release.
If you're upgrading from an older version of Roundup you *must* follow
the "Software Upgrade" guidelines given in the maintenance documentation.
Unfortunately, the Zope frontend for Roundup is currently broken. I hope to
revive it in a future 0.6 bugfix release.
The gadfly backend has now been removed, having served its purpose as a
template for other RDBMS implementations. It is replaced by the sqlite and
mysql backends.
Roundup requires python 2.1.3 or later for correct operation.
The 0.6 release has lots of new goodies including:
- new instant-gratification Demo Mode ("python demo.py" :)
- added mysql backend (see doc/mysql.txt for details)
- web interface cleanups including nicer history display, nicer index
navigation and nicer popup list windows
- searching of date ranges
- better international support, including utf-8 email handling and ability
to display localized dates in web interface.
- more documentation including revamped design document, unix manual pages
and some FAQ entries
- significantly more powerful form handling allowing editing of multiple
items and creation of multiple items
- tracker templates can contain subdirectories and static files (e.g.
images) and we may now distribute templates separately from Roundup.
Template HTML files now have a .html extension too.
- user registration is now a two-step process, with confirmation from the
email address supplied in the registration form, and we also have a
password reset feature for forgotten password / login
- Windows Service mode for roundup-server when daemonification is
attempted on Windows
- lots of speed enhancements, making the web interface much more responsive
- fixed issues with dumb email or web clients
- email system handles more SMTP and POP features (TLS, APOP, ...)
- lots more little tweaks and back-end work...
Source and documentation is available at the website:
http://roundup.sourceforge.net/
Release Info (via download page):
http://sourceforge.net/projects/roundup
Mailing lists - the place to ask questions:
http://sourceforge.net/mail/?group_id=31577
About Roundup
=============
Roundup is a simple-to-use and -install issue-tracking system with
command-line, web and e-mail interfaces. It is based on the winning design
from Ka-Ping Yee in the Software Carpentry "Track" design competition.
Note: Ping is not responsible for this project. The contact for this project
is richard(a)users.sourceforge.net.
Roundup manages a number of issues (with flexible properties such as
"description", "priority", and so on) and provides the ability to:
(a) submit new issues,
(b) find and edit existing issues, and
(c) discuss issues with other participants.
The system will facilitate communication among the participants by managing
discussions and notifying interested parties when issues are edited. One of
the major design goals for Roundup that it be simple to get going. Roundup
is therefore usable "out of the box" with any python 2.1+ installation. It
doesn't even need to be "installed" to be operational, though a
disutils-based install script is provided.
It comes with two issue tracker templates (a classic bug/feature tracker and
a minimal skeleton) and six database back-ends (anydbm, bsddb, bsddb3, sqlite,
metakit and mysql).
1
1
PyQt v3.8 has been released and can be downloaded from
http://www.riverbankcomputing.co.uk/pyqt/
Highlights of this release include the addition of many operators to existing
classes and full support for Qt v3.2.0.
PyQt is a comprehensive set of Python bindings for Trolltech's Qt GUI toolkit.
It includes approximately 300 classes and 5,750 methods including OpenGL, SQL
and XML support as well as a rich set of GUI widgets. It also includes a
utility to generate Python code from Qt Designer, Qt's GUI builder.
PyQt runs on UNIX/Linux, Windows and the Sharp Zaurus.
PyQt is licensed under the GPL, commercial, educational and non-commercial
licenses.
Phil
1
0
This FAQ collects questions about using Python on Windows. Many of
the more specific questions deal with one Windows bug or another; it's
not clear how many of these bugs are still relevant for users of
Windows XP or 2000.
Please *don't* send me comments about the questions, because I can't
tell which comments are correct and which aren't, so I'm not planning
to make any changes to the file. A Windows-using maintainer is
desperately needed. If you want to be the maintainer, just grab a
copy of the reStructured Text source from
http://www.python.org/doc/faq/windows.ht, edit away, and send your
updated draft to the python.org webmaster address.
--amk
Title: Python Windows FAQ
Content-type: text/x-rst
====================================
Python Windows FAQ
====================================
:Date: $Date: 2003/08/14 20:41:20 $
:Version: $Revision: 1.2 $
:Web site: http://www.python.org/
.. contents::
.. sectnum::
How do I run a Python program under Windows?
----------------------------------------------------
This is not necessarily a straightforward question. If you are already
familiar with running programs from the Windows command line then
everything will seem obvious; otherwise, you might need a little more
guidance. There are also differences between Windows 95, 98, NT, ME,
2000 and XP which can add to the confusion.
Unless you use some sort of integrated development environment,
you will end up *typing* Windows commands into what is variously referred
to as a "DOS window" or "Command prompt window". Usually you can
create such a window from your Start menu; under Windows 2000
the menu selection is
"Start | Programs | Accessories | Command Prompt". You should be
able to recognize when you have started such a window because you will
see a Windows "command prompt", which usually looks like this::
C:\>
The letter may be different, and there might be other things after it,
so you might just as easily see something like::
D:\Steve\Projects\Python>
depending on how your computer has been set up and what else you have
recently done with it. Once you have started such a window, you are
well on the way to running Python programs.
You need to realize that your Python scripts have to be processed by
another program called the Python interpreter. The
interpreter reads your script, compiles it into bytecodes, and then executes the bytecodes to run your
program. So, how do you arrange for the interpreter to handle your
Python?
First, you need to make sure that your command window recognises the
word "python" as an instruction to start the interpreter. If you have
opened a command window, you should try entering the command ``python``
and hitting return. You should then see something like::
Python 2.2 (#28, Dec 21 2001, 12:21:22) [MSC 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
You have started the interpreter in "interactive mode". That means you
can enter Python statements or expressions interactively and have them
executed or evaluated while you wait. This is one of Python's
strongest features. Check it by entering a few expressions of your
choice and seeing the results::
>>> print "Hello"
Hello
>>> "Hello" * 3
HelloHelloHello
Many people use the interactive mode as a convenient yet highly
programmable calculator.
When you want to end your interactive Python session, hold the Ctrl
key down while you enter a Z, then hit the "Enter" key to get back to
your Windows command prompt.
You may also find that you have a
Start-menu entry such as "Start | Programs | Python 2.2 | Python
(command line)" that results in you seeing the ">>>" prompt in a new
window. If so, the window will disappear after you enter the
Ctrl-Z character; Windows is running a single "python" command in the window,
and closes it when you terminate the interpreter.
If the ``python`` command, instead of displaying the interpreter
prompt ">>>", gives you a message like::
'python' is not recognized as an internal or external command,
operable program or batch file.
or::
Bad command or filename
then you need to make sure that your computer knows where to find the
Python interpreter. To do this you will have to modify a setting
called PATH, which is a list of directories where Windows
will look for programs. You should arrange for Python's
installation directory to be added to the PATH of every command window
as it starts. If you installed Python fairly recently then the command ::
dir C:\py*
will probably tell you where it is installed; the usual location is
something like C:\Python23. Otherwise you will be reduced to a search of your
whole disk ... use "Tools | Find"
or hit the "Search" button and look for "python.exe". Supposing you
discover that Python is installed in the C:\Python23 directory (the
default at the time of writing), you should make sure that
entering the command ::
c:\Python23\python
starts up the interpreter as above (and don't forget you'll need a
"CTRL-Z" and an "Enter" to get out of it). Once you have verified the
directory, you need to add it to the start-up routines your computer
goes through. For older versions of Windows the easiest way to do
this is to edit the C:\AUTOEXEC.BAT file. You would want to add a line
like the following to AUTOEXEC.BAT::
PATH C:\Python23;%PATH%
For Windows NT, 2000 and (I assume) XP, you will need to add a string
such as ::
;C:\Python23
to the current setting for the PATH environment variable, which you
will find in the properties window of "My Computer" under the
"Advanced" tab. Note that if you have sufficient privilege you might
get a choice of installing the settings either for the Current User or
for System. The latter is preferred if you want everybody to be able
to run Python on the machine.
If you aren't confident doing any of these manipulations yourself, ask
for help! At this stage you may want to reboot your system
to make absolutely sure the new setting has taken effect. You probably
won't need to reboot for Windows NT, XP or 2000. You can also avoid it in
earlier versions by editing the file C:\WINDOWS\COMMAND\CMDINIT.BAT
instead of AUTOEXEC.BAT.
You should now be able to start a new command window, enter ``python``
at the "C:>" (or whatever) prompt, and see the ">>>" prompt that
indicates the Python interpreter is reading interactive commands.
Let's suppose you have a program called "pytest.py" in directory
"C:\Steve\Projects\Python". A session to run that program might look
like this::
C:\> cd \Steve\Projects\Python
C:\Steve\Projects\Python> python pytest.py
Because you added a file name to the command to start the interpreter,
when it starts up it reads the Python script in the named file,
compiles it, executes it, and terminates, so you see another "C:\>"
prompt. You might also have entered ::
C:\> python \Steve\Projects\Python\pytest.py
if you hadn't wanted to change your current directory.
Under NT, 2000 and XP you may well find that the installation process
has also arranged that the command ``pytest.py``
(or, if the file isn't in the current directory,
``C:\Steve\Projects\Python\pytest.py``)
will automatically recognize the ".py" extension and run the Python
interpreter on the named file. Using this feature is fine, but *some*
versions of Windows have bugs which mean that this form isn't exactly
equivalent to using the interpreter explicitly, so be careful.
The important things to remember are:
1. Start Python from the Start Menu, or make sure the PATH is set
correctly so Windows can find the Python interpreter. ::
python
should give you a '>>>" prompt from the Python interpreter. Don't
forget the CTRL-Z and ENTER to terminate the interpreter (and, if you
started the window from the Start Menu, make the window disappear).
2. Once this works, you run programs with commands::
python {program-file}
3. When you know the commands to use you can build Windows shortcuts
to run the Python interpreter on any of your scripts, naming
particular working directories, and adding them to your menus.
Take a look at ::
python --help
if your needs are complex.
4. Interactive mode (where you see the ">>>" prompt) is best used
for checking that individual statements and expressions do
what you think they will, and for developing code by experiment.
How do I make python scripts executable?
----------------------------------------------
On Windows 2000, the standard Python installer already associates the
.py extension with a file type (Python.File) and gives that file type
an open command that runs the interpreter (D:\Program
Files\Python\python.exe "%1" %*). This is enough to make scripts
executable from the command prompt as 'foo.py'. If you'd rather be
able to execute the script by simple typing 'foo' with no extension
you need to add .py to the PATHEXT environment variable.
On Windows NT, the steps taken by the installer as described above
allow you to run a script with 'foo.py', but a longtime bug in the NT
command processor prevents you from redirecting the input or output of
any script executed in this way. This is often important.
The incantation for making a Python script executable under WinNT
is to give the file an extension of .cmd and add the following as the first
line::
@setlocal enableextensions & python -x %~f0 %* & goto :EOF
Where is Freeze for Windows?
------------------------------------
"Freeze" is a program that allows you to ship a Python program
as a single stand-alone executable file. It is *not* a compiler;
your programs don't run any faster, but they are more easily
distributable, at least to platforms with the same OS and CPU. Read the
README file of the freeze program for more disclaimers.
You can use freeze on Windows, but you must download the source
tree (see http://www.python.org/download/download_source.html).
The freeze program is in the ``Tools\freeze`` subdirectory of the source
tree.
You need the Microsoft VC++ compiler, and you probably need to build
Python. The required project files are in the PCbuild directory.
Is a ``*.pyd`` file the same as a DLL?
------------------------------------------
Yes, .pyd files are dll's, but there are a few differences. If you
have a DLL named foo.pyd, then it must have a function initfoo(). You
can then write Python "import foo", and Python will search for foo.pyd
(as well as foo.py, foo.pyc) and if it finds it, will attempt to call
initfoo() to initialize it. You do not link your .exe with foo.lib,
as that would cause Windows to require the DLL to be present.
Note that the search path for foo.pyd is PYTHONPATH, not the same as
the path that Windows uses to search for foo.dll. Also, foo.pyd need
not be present to run your program, whereas if you linked your program
with a dll, the dll is required. Of course, foo.pyd is required if
you want to say "import foo". In a DLL, linkage is declared in the
source code with __declspec(dllexport). In a .pyd, linkage is defined
in a list of available functions.
How can I embed Python into a Windows application?
----------------------------------------------------------
Embedding the Python interpreter in a Windows app can be summarized as
follows:
1. Do _not_ build Python into your .exe file directly. On Windows,
Python must be a DLL to handle importing modules that are themselves
DLL's. (This is the first key undocumented fact.) Instead, link to
pythonNN.dll; it is typically installed in c:\Windows\System.
NN is the Python version, a number such as "23" for Python 2.3.
You can link to Python statically or dynamically. Linking
statically means linking against pythonNN.lib, while dynamically
linking means linking against pythonNN.dll. The drawback to
dynamic linking is that your app won't run if pythonNN.dll does not
exist on your system.
(General note: pythonNN.lib is the so-called "import lib" corresponding
to python.dll. It merely defines symbols for the linker.)
Linking dynamically greatly simplifies link options; everything happens
at run time. Your code must load pythonNN.dll using the Windows
LoadLibraryEx() routine. The code must also use access routines and
data in pythonNN.dll (that is, Python's C API's) using pointers
obtained by the Windows GetProcAddress() routine. Macros can make
using these pointers transparent to any C code that calls routines in
Python's C API.
Borland note: convert pythonNN.lib to OMF format using Coff2Omf.exe
first.
2. If you use SWIG, it is easy to create a Python "extension module"
that will make the app's data and methods available to Python. SWIG
will handle just about all the grungy details for you. The result is C
code that you link *into* your .exe file (!) You do _not_ have to
create a DLL file, and this also simplifies linking.
3. SWIG will create an init function (a C function) whose name depends
on the name of the extension module. For example, if the name of the
module is leo, the init function will be called initleo(). If you use
SWIG shadow classes, as you should, the init function will be called
initleoc(). This initializes a mostly hidden helper class used by the
shadow class.
The reason you can link the C code in step 2 into your .exe file is that
calling the initialization function is equivalent to importing the
module into Python! (This is the second key undocumented fact.)
4. In short, you can use the following code to initialize the Python
interpreter with your extension module. ::
#include "python.h"
...
Py_Initialize(); // Initialize Python.
initmyAppc(); // Initialize (import) the helper class.
PyRun_SimpleString("import myApp") ; // Import the shadow class.
5. There are two problems with Python's C API which will become apparent
if you use a compiler other than MSVC, the compiler used to build
pythonNN.dll.
Problem 1: The so-called "Very High Level" functions that take FILE *
arguments will not work in a multi-compiler environment because each compiler's
notion of a struct FILE will be different. From an implementation
standpoint these are very _low_ level functions.
Problem 2: SWIG generates the following code when generating wrappers to
void functions::
Py_INCREF(Py_None);
_resultobj = Py_None;
return _resultobj;
Alas, Py_None is a macro that expands to a reference to a complex data
structure called _Py_NoneStruct inside pythonNN.dll. Again, this code
will fail in a mult-compiler environment. Replace such code by::
return Py_BuildValue("");
It may be possible to use SWIG's %typemap command to make the change
automatically, though I have not been able to get this to work (I'm a
complete SWIG newbie).
6. Using a Python shell script to put up a Python interpreter window
from inside your Windows app is not a good idea; the resulting window
will be independent of your app's windowing system. Rather, you (or the
wxPythonWindow class) should create a "native" interpreter window. It
is easy to connect that window to the Python interpreter. You can
redirect Python's i/o to _any_ object that supports read and write, so
all you need is a Python object (defined in your extension module) that
contains read() and write() methods.
How do I use Python for CGI?
-------------------------------------------------------
On the Microsoft IIS server or on the Win95 MS Personal Web Server you
set up Python in the same way that you would set up any other
scripting engine.
Run regedt32 and go to::
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W3SVC\Parameters\ScriptMap
and enter the following line (making any specific changes that your system may need)::
.py :REG_SZ: c:\<path to python>\python.exe -u %s %s
This line will allow you to call your script with a simple reference like:
http://yourserver/scripts/yourscript.py
provided "scripts" is an "executable" directory for your server (which
it usually is by default).
The "-u" flag specifies unbuffered and binary mode for stdin - needed when working with binary data.
In addition, it is recommended that using
".py" may not be a good idea for the file extensions when used in this
context (you might want to reserve ``*.py`` for support modules and
use ``*.cgi`` or ``*.cgp`` for "main program" scripts).
In order to set up Internet Information Services 5 to use Python for CGI processing, please see the following links:
http://www.e-coli.net/pyiis_server.html (for Win2k Server)
http://www.e-coli.net/pyiis.html (for Win2k pro)
Configuring Apache is much simpler.
In the Apache configuration file ``httpd.conf``, add the following line at
the end of the file::
ScriptInterpreterSource Registry
Then, give your Python CGI-scripts the extension .py and put them in the cgi-bin directory.
How do I keep editors from inserting tabs into my Python source?
------------------------------------------------------------------
The FAQ does not recommend using tabs, and `the Python style guide <http://www.python.org/peps/pep-0008.html>`_
recommends 4 spaces for distributed Python code; this is also the
Emacs python-mode default.
Under any editor, mixing tabs and spaces is a bad idea. MSVC is no
different in this respect, and is easily configured to use spaces:
Take Tools -> Options -> Tabs, and for file type "Default" set "Tab
size" and "Indent size" to 4, and select the "Insert spaces" radio
button.
If you suspect mixed tabs and spaces are causing problems in leading
whitespace, run Python with the -t switch or run
``Tools/Scripts/tabnanny.py`` to check a directory tree in batch mode.
How do I check for a keypress without blocking?
----------------------------------------------------
Use the msvcrt module. This is a standard Windows-specific extension
module. It defines a function kbhit() which checks whether a keyboard
hit is present, and getch() which gets one character without echoing
it.
How do I emulate os.kill() in Windows?
---------------------------------------------
Use win32api::
def kill(pid):
"""kill function for Win32"""
import win32api
handle = win32api.OpenProcess(1, 0, pid)
return (0 != win32api.TerminateProcess(handle, 0))
Why does os.path.isdir() fail on NT shared directories?
--------------------------------------------------------------
The solution appears to be always append the "\\" on
the end of shared drives. ::
>>> import os
>>> os.path.isdir( '\\\\rorschach\\public')
0
>>> os.path.isdir( '\\\\rorschach\\public\\')
1
It helps to think of share points as being like drive letters.
Example::
k: is not a directory
k:\ is a directory
k:\media is a directory
k:\media\ is not a directory
The same rules apply if you substitute "k:" with "\\conky\foo"::
\\conky\foo is not a directory
\\conky\foo\ is a directory
\\conky\foo\media is a directory
\\conky\foo\media\ is not a directory
cgi.py (or other CGI programming) doesn't work sometimes on NT or win95!
-----------------------------------------------------------------------------
Be sure you have the latest python.exe, that you are using
python.exe rather than a GUI version of Python and that you
have configured the server to execute ::
"...\python.exe -u ..."
for the CGI execution. The -u (unbuffered) option on NT and
Win95 prevents the interpreter from altering newlines in the
standard input and output. Without it post/multipart requests
will seem to have the wrong length and binary (e.g. GIF)
responses may get garbled (resulting in broken images, PDF files,
and other binary downloads failing).
Why doesn't os.popen() work in PythonWin on NT?
-------------------------------------------------------
The reason that os.popen() doesn't work from within PythonWin is due
to a bug in Microsoft's C Runtime Library (CRT). The CRT assumes you
have a Win32 console attached to the process.
You should use the win32pipe module's popen() instead which doesn't
depend on having an attached Win32 console.
Example::
import win32pipe
f = win32pipe.popen('dir /c c:\\')
print f.readlines()
f.close()
Why doesn't os.popen()/win32pipe.popen() work on Win9x?
---------------------------------------------------------------
There is a bug in Win9x that prevents os.popen/win32pipe.popen* from
working. The good news is there is a way to work around this problem.
The Microsoft Knowledge Base article that you need to lookup is:
Q150956. You will find links to the knowledge base at:
http://www.microsoft.com/kb.
PyRun_SimpleFile() crashes on Windows but not on Unix; why?
------------------------------------------------------------
This is very sensitive to the compiler vendor, version and (perhaps)
even options. If the FILE* structure in your embedding program isn't
the same as is assumed by the Python interpreter it won't work.
The Python 1.5.* DLLs (python15.dll) are all compiled
with MS VC++ 5.0 and with multithreading-DLL options (``/MD``).
If you can't change compilers or flags, try using Py_RunSimpleString().
A trick to get it to run an arbitrary file is to construct a call to
execfile() with the name of your file as argument.
Also note that you can not mix-and-match Debug and Release versions. If you wish to use the Debug Multithreaded DLL, then your module _must_ have an "_d" appended to the base name.
Importing _tkinter fails on Windows 95/98: why?
------------------------------------------------
Sometimes, the import of _tkinter fails on Windows 95 or 98,
complaining with a message like the following::
ImportError: DLL load failed: One of the library files needed
to run this application cannot be found.
It could be that you haven't installed Tcl/Tk, but if you did
install Tcl/Tk, and the Wish application works correctly,
the problem may be that its installer didn't
manage to edit the autoexec.bat file correctly. It tries to add a
statement that changes the PATH environment variable to include
the Tcl/Tk 'bin' subdirectory, but sometimes this edit doesn't
quite work. Opening it with notepad usually reveals what the
problem is.
(One additional hint, noted by David Szafranski: you can't use
long filenames here; e.g. use C:\PROGRA~1\Tcl\bin instead of
C:\Program Files\Tcl\bin.)
How do I extract the downloaded documentation on Windows?
------------------------------------------------------------
Sometimes, when you download the documentation package to a Windows
machine using a web browser, the file extension of the saved file
ends up being .EXE. This is a mistake; the extension should be .TGZ.
Simply rename the downloaded file to have the .TGZ extension, and
WinZip will be able to handle it. (If your copy of WinZip doesn't,
get a newer one from http://www.winzip.com.)
Missing cw3215mt.dll (or missing cw3215.dll)
----------------------------------------------------
Sometimes, when using Tkinter on Windows, you get an error that
cw3215mt.dll or cw3215.dll is missing.
Cause: you have an old Tcl/Tk DLL built with cygwin in your path
(probably C:\Windows). You must use the Tcl/Tk DLLs from the
standard Tcl/Tk installation (Python 1.5.2 comes with one).
Warning about CTL3D32 version from installer
----------------------------------------------------
The Python installer issues a warning like this::
This version uses CTL3D32.DLL whitch is not the correct version.
This version is used for windows NT applications only.
[Tim Peters]
This is a Microsoft DLL, and a notorious
source of problems. The message means what it says: you have the wrong version
of this DLL for your operating system. The Python installation did not
cause this -- something else you installed previous to this overwrote the
DLL that came with your OS (probably older shareware of some sort, but
there's no way to tell now). If you search for "CTL3D32" using any search
engine (AltaVista, for example), you'll find hundreds and hundreds of web
pages complaining about the same problem with all sorts of installation
programs. They'll point you to ways to get the correct version reinstalled
on your system (since Python doesn't cause this, we can't fix it).
David A Burton has written a little program to fix this. Go to
http://www.burtonsys.com/download.html and click on "ctl3dfix.zip"
1
0
The GUI FAQ is really minimal; there weren't many questions in the old
FAQ about GUIs, so this FAQ consists of two general questions about
what GUI toolkit are available from Python, and two very specific
Tkinter questions.
--amk
Title: Graphic User Interface FAQ
Content-type: text/x-rst
====================================
Graphic User Interface FAQ
====================================
:Date: $Date: 2003/08/15 21:14:43 $
:Version: $Revision: 1.2 $
:Web site: http://www.python.org/
.. contents::
.. sectnum::
General GUI Questions
============================
What platform-independent GUI toolkits exist for Python?
----------------------------------------------------------------
Depending on what platform(s) you are aiming at, there are several.
Tkinter
''''''''''''
Standard builds of Python include an object-oriented interface to the
Tcl/Tk widget set, called Tkinter. This is probably the easiest to
install and use. For more info about Tk, including pointers to the
source, see the Tcl/Tk home page at http://www.tcl.tk. Tcl/Tk is
fully portable to the MacOS, Windows, and Unix platforms.
wxWindows
'''''''''''''
wxWindows is a portable GUI class library written in C++ that's a
portable interface to various platform-specific libraries; wxPython is
a Python interface to wxWindows. wxWindows supports Windows and MacOS;
on Unix variants, it supports both GTk+ and Motif toolkits.
wxWindows preserves the look and feel of the underlying graphics
toolkit, and there is quite a rich widget set and collection of GDI
classes. See `the wxWindows page <http://www.wxwindows.org>`_ for more
details.
`wxPython <http://alldunn.com/wxPython>`_ is an extension module that
wraps many of the wxWindows C++ classes, and is quickly gaining
popularity amongst Python developers. You can get wxPython as part of
the source or CVS distribution of wxWindows, or directly from its home
page.
GTk+
'''''''''''
PyGTk bindings for the GTk+ Toolkit by James Henstridge are available;
see ftp://ftp.daa.com.au/pub/james/python.
Qt
''''''
There are bindings available for the Qt toolkit (PyQt). and for KDE
(PyKDE); see http://www.thekompany.com/projects/pykde. If you're writing
open source software, you don't need to pay for PyQt, but if you want to write
proprietary applications, you must buy a license from XXX.
For OpenGL bindings, see `PyOpenGL <http://pyopengl.sourceforge.net>`_.
What platform-specific GUI toolkits exist for Python?
----------------------------------------------------------------
`The Mac port <http://www.python.org/download/download_mac.html>`_ by
Jack Jansen has a rich and ever-growing set of modules that support
the native Mac toolbox calls. The port includes support for MacOS9
and MacOS X's Carbon libraries. By installing the `PyObjc Objective-C
bridge <http://pyobjc.sourceforge.net>`_, Python programs can use
MacOS X's Cocoa libraries. See the documentation that comes with the
Mac port.
`Pythonwin <http://www.python.org/windows>`_ by Mark Hammond
includes an interface to the Microsoft Foundation
Classes and a Python programming environment using it that's written
mostly in Python.
Tkinter
=====================
How do I freeze Tkinter applications?
---------------------------------------------
Freeze is a tool to create stand-alone applications. When freezing
Tkinter applications, the applications will not be truly stand-alone,
as the application will still need the Tcl and Tk libraries.
One solution is to ship the application with the tcl and tk libraries,
and point to them at run-time using the TCL_LIBRARY and TK_LIBRARY
environment variables.
To get truly stand-alone applications, the Tcl scripts that form
the library have to be integrated into the application as well. One
tool supporting that is SAM (stand-alone modules), which is part
of the Tix distribution (http://tix.mne.com). Build Tix with SAM
enabled, perform the appropriate call to Tclsam_init etc inside
Python's Modules/tkappinit.c, and link with libtclsam
and libtksam (you might include the Tix libraries as well).
Can I have Tk events handled while waiting for I/O?
-----------------------------------------------------------
Yes, and you don't even need threads! But you'll have to
restructure your I/O code a bit. Tk has the equivalent of Xt's
XtAddInput() call, which allows you to register a callback function
which will be called from the Tk mainloop when I/O is possible on a
file descriptor. Here's what you need::
from Tkinter import tkinter
tkinter.createfilehandler(file, mask, callback)
The file may be a Python file or socket object (actually, anything
with a fileno() method), or an integer file descriptor. The mask is
one of the constants tkinter.READABLE or tkinter.WRITABLE. The
callback is called as follows::
callback(file, mask)
You must unregister the callback when you're done, using ::
tkinter.deletefilehandler(file)
Note: since you don't know *how many bytes* are available for reading,
you can't use the Python file object's read or readline methods, since
these will insist on reading a predefined number of bytes. For
sockets, the recv() or recvfrom() methods will work fine; for other
files, use os.read(file.fileno(), maxbytecount).
I can't get key bindings to work in Tkinter: why?
---------------------------------------------------
An often-heard complaint is that event handlers bound to events
with the bind() method don't get handled even when the appropriate
key is pressed.
The most common cause is that the widget to which the binding applies
doesn't have "keyboard focus". Check out the Tk documentation
for the focus command. Usually a widget is given the keyboard
focus by clicking in it (but not for labels; see the takefocus
option).
1
0
The FAQ parade continues with the Extending/Embedding FAQ, covering
Python's C API.
Comments are welcome. (Volunteers to maintain any of these FAQs
would be even more welcome.)
--amk
Title: Python Extending/Embedding FAQ
Content-type: text/x-rst
====================================
Extending/Embedding FAQ
====================================
:Date: $Date: 2003/08/14 20:47:18 $
:Version: $Revision: 1.2 $
:Web site: http://www.python.org/
.. contents::
.. sectnum::
Can I create my own functions in C?
------------------------------------------
Yes, you can create built-in modules containing functions, variables,
exceptions and even new types in C. This is explained in the document
"Extending and Embedding the Python Interpreter"
(http://www.python.org/doc/current/ext/ext.html).
Most intermediate or advanced Python books will also
cover this topic.
Can I create my own functions in C++?
--------------------------------------------
Yes, using the C compatibility features found in C++.
Place ``extern "C" { ... }`` around the Python include files and put
``extern "C"`` before each function that is going to be called by the
Python interpreter. Global or static C++ objects with constructors
are probably not a good idea.
Writing C is hard; are there any alternatives?
---------------------------------------------------
There are a number of alternatives to writing your own C extensions,
depending on what you're trying to do.
If you need more speed, `Psyco <http://psyco.sourceforge.net/>`_ generates x86 assembly code
from Python bytecode. You can use Psyco to compile the most
time-critical functions in your code, and gain a significant
improvement with very little effort, as long as you're running on a
machine with an x86-compatible processor.
`Pyrex <http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/>`_ is a compiler that accepts a slightly modified form of Python
and generates the corresponding C code. Pyrex makes it possible to write
an extension without having to learn Python's C API.
If you need to interface to some C library for which no Python
extension currently exists, you can try wrapping the library's data
types and functions with a tool such as `SWIG <http://www.swig.org>`_.
For C++ libraries, you can look at `SIP <http://www.riverbankcomputing.co.uk/sip/>`_, `CXX <http://cxx.sourceforge.net/>`_, `Boost
<http://www.boost.org/libs/python/doc/index.html>`_, or `Weave <http://www.scipy.org/site_content/weave>`_.
How can I execute arbitrary Python statements from C?
------------------------------------------------------------
The highest-level function to do this is ``PyRun_SimpleString()`` which takes
a single string argument to be executed in the context of the module
``__main__`` and returns 0 for success and -1 when an exception occurred
(including ``SyntaxError``). If you want more control, use ``PyRun_String()``;
see the source for ``PyRun_SimpleString()`` in Python/pythonrun.c.
How can I evaluate an arbitrary Python expression from C?
----------------------------------------------------------------
Call the function ``PyRun_String()`` from the previous question with the
start symbol ``Py_eval_input``; it
parses an expression, evaluates it and returns its value.
How do I extract C values from a Python object?
------------------------------------------------------
That depends on the object's type. If it's a tuple,
``PyTupleSize(o)`` returns its length and ``PyTuple_GetItem(o, i)``
returns its i'th item. Lists have similar functions, ``PyListSize(o)``
and ``PyList_GetItem(o, i)``.
For strings, ``PyString_Size(o)`` returns
its length and ``PyString_AsString(o)`` a pointer to its value.
Note that Python strings may contain null bytes so C's ``strlen()``
should not be used.
To test the type of an object, first make sure
it isn't NULL, and then use ``PyString_Check(o)``, ``PyTuple_Check(o)``,
``PyList_Check(o)``, etc.
There is also a high-level API to Python objects which is
provided by the so-called 'abstract' interface -- read
``Include/abstract.h`` for further details. It allows
interfacing with any kind of Python sequence
using calls like ``PySequence_Length()``, ``PySequence_GetItem()``, etc.)
as well as many other useful protocols.
How do I use Py_BuildValue() to create a tuple of arbitrary length?
--------------------------------------------------------------------------
You can't. Use ``t = PyTuple_New(n)`` instead, and fill it with
objects using ``PyTuple_SetItem(t, i, o)`` -- note that this "eats" a
reference count of ``o``, so you have to ``Py_INCREF`` it.
Lists have similar functions ``PyList_New(n)`` and
``PyList_SetItem(l, i, o)``. Note that you *must* set all the tuple items to
some value before you pass the tuple to Python code --
``PyTuple_New(n)`` initializes them to NULL, which isn't a valid Python
value.
How do I call an object's method from C?
-----------------------------------------------
The ``PyObject_CallMethod()`` function can be used to call an arbitrary
method of an object. The parameters are the object, the name of the
method to call, a format string like that used with ``Py_BuildValue()``, and the argument values::
PyObject *
PyObject_CallMethod(PyObject *object, char *method_name,
char *arg_format, ...);
This works for any object that has methods -- whether built-in or
user-defined. You are responsible for eventually ``Py_DECREF``'ing the
return value.
To call, e.g., a file object's "seek" method with arguments 10, 0
(assuming the file object pointer is "f")::
res = PyObject_CallMethod(f, "seek", "(ii)", 10, 0);
if (res == NULL) {
... an exception occurred ...
}
else {
Py_DECREF(res);
}
Note that since ``PyObject_CallObject()`` *always* wants a tuple for the
argument list, to call a function without arguments, pass "()" for the
format, and to call a function with one argument, surround the argument
in parentheses, e.g. "(i)".
How do I catch the output from PyErr_Print() (or anything that prints to stdout/stderr)?
-----------------------------------------------------------------------------------------------
In Python code, define an object that supports the ``write()`` method.
Assign this object to ``sys.stdout`` and ``sys.stderr``.
Call print_error, or just allow the standard traceback mechanism to
work. Then, the output will go wherever your ``write()`` method sends it.
The easiest way to do this is to use the StringIO class in the standard
library.
Sample code and use for catching stdout::
>>> class StdoutCatcher:
... def __init__(self):
... self.data = ''
... def write(self, stuff):
... self.data = self.data + stuff
...
>>> import sys
>>> sys.stdout = StdoutCatcher()
>>> print 'foo'
>>> print 'hello world!'
>>> sys.stderr.write(sys.stdout.data)
foo
hello world!
How do I access a module written in Python from C?
---------------------------------------------------------
You can get a pointer to the module object as follows::
module = PyImport_ImportModule("<modulename>");
If the module hasn't been imported yet (i.e. it is not yet present in
``sys.modules``), this initializes the module; otherwise it simply returns
the value of ``sys.modules["<modulename>"]``. Note that it doesn't enter
the module into any namespace -- it only ensures it has been
initialized and is stored in ``sys.modules``.
You can then access the module's attributes (i.e. any name defined in
the module) as follows::
attr = PyObject_GetAttrString(module, "<attrname>");
Calling ``PyObject_SetAttrString()`` to assign to variables in the module also works.
How do I interface to C++ objects from Python?
------------------------------------------------------
Depending on your requirements, there are many approaches. To do
this manually, begin by reading `the "Extending and Embedding" document <http://www.python.org/doc/ext/>`_. Realize
that for the Python run-time system, there isn't a whole lot of
difference between C and C++ -- so the strategy of building a new Python
type around a C structure (pointer) type will also work for C++
objects.
For C++ libraries, you can look at `SIP <http://www.riverbankcomputing.co.uk/sip/>`_, `CXX <http://cxx.sourceforge.net/>`_, `Boost
<http://www.boost.org/libs/python/doc/index.html>`_, or `Weave <http://www.scipy.org/site_content/weave>`_.
`SWIG <http://www.swig.org>`_ is a similar automated tool that only supports C libraries.
I added a module using the Setup file and the make fails; why?
----------------------------------------------------------------------
Setup must end in a newline, if there is no newline there, the build
process fails. (Fixing this requires some ugly shell script hackery,
and this bug is so minor that it doesn't seem worth the effort.)
How do I debug an extension?
------------------------------------
When using GDB with dynamically loaded extensions, you can't set a
breakpoint in your extension until your extension is loaded.
In your ``.gdbinit`` file (or interactively), add the command::
br _PyImport_LoadDynamicModule
Then, when you run GDB::
$ gdb /local/bin/python
gdb) run myscript.py
gdb) continue # repeat until your extension is loaded
gdb) finish # so that your extension is loaded
gdb) br myfunction.c:50
gdb) continue
I want to compile a Python module on my Linux system, but some files are missing. Why?
-------------------------------------------------------------------------------------------------
Most packaged versions of Python don't include the
/usr/lib/python2.x/config/ directory, which contains various files required
for compiling Python extensions.
For Red Hat, install the python-devel RPM to get the necessary files.
For Debian, run ``apt-get install python-devel``.
What does "SystemError: _PyImport_FixupExtension: module yourmodule not loaded" mean?
-------------------------------------------------------------------------------------------------------
This means that you have created an extension module named "yourmodule", but your module init function does not initialize with that name.
Every module init function will have a line similar to::
module = Py_InitModule("yourmodule", yourmodule_functions);
If the string passed to this function is not the same name as your
extenion module, the ``SystemError`` exception will be raised.
How do I tell "incomplete input" from "invalid input"?
--------------------------------------------------------------------------------
Sometimes you want to emulate the Python interactive interpreter's
behavior, where it gives you a continuation prompt when the input
is incomplete (e.g. you typed the start of an "if" statement
or you didn't close your parentheses or triple string quotes),
but it gives you a syntax error message immediately when the input
is invalid.
In Python you can use the ``codeop`` module, which approximates the
parser's behavior sufficiently. IDLE uses this, for example.
The easiest way to do it in C is to call ``PyRun_InteractiveLoop()``
(perhaps in a separate thread) and let the Python interpreter handle
the input for you. You can also set the ``PyOS_ReadlineFunctionPointer``
to point at your custom input function. See ``Modules/readline.c`` and
``Parser/myreadline.c`` for more hints.
However sometimes you have to run the embedded Python interpreter in
the same thread as your rest application and you can't allow the
``PyRun_InteractiveLoop()`` to stop while waiting for user input. The
one solution then is to call ``PyParser_ParseString()`` and test for
``e.error`` equal to ``E_EOF``, which means the input is incomplete).
Here's a sample code fragment, untested, inspired by code from Alex Farber::
#include <Python.h>
#include <node.h>
#include <errcode.h>
#include <grammar.h>
#include <parsetok.h>
#include <compile.h>
int testcomplete(char *code)
/* code should end in \n */
/* return -1 for error, 0 for incomplete, 1 for complete */
{
node *n;
perrdetail e;
n = PyParser_ParseString(code, &_PyParser_Grammar,
Py_file_input, &e);
if (n == NULL) {
if (e.error == E_EOF)
return 0;
return -1;
}
PyNode_Free(n);
return 1;
}
Another solution is trying to compile the received string with
``Py_CompileString()``. If it compiles without errors, try to execute the returned
code object by calling ``PyEval_EvalCode()``. Otherwise save the input for
later. If the compilation fails, find out if it's an error or just
more input is required - by extracting the message string from the
exception tuple and comparing it to the string "unexpected EOF while parsing".
Here is a complete example using the GNU readline library (you may
want to ignore SIGINT while calling readline())::
#include <stdio.h>
#include <readline.h>
#include <Python.h>
#include <object.h>
#include <compile.h>
#include <eval.h>
int main (int argc, char* argv[])
{
int i, j, done = 0; /* lengths of line, code */
char ps1[] = ">>> ";
char ps2[] = "... ";
char *prompt = ps1;
char *msg, *line, *code = NULL;
PyObject *src, *glb, *loc;
PyObject *exc, *val, *trb, *obj, *dum;
Py_Initialize ();
loc = PyDict_New ();
glb = PyDict_New ();
PyDict_SetItemString (glb, "__builtins__", PyEval_GetBuiltins ());
while (!done)
{
line = readline (prompt);
if (NULL == line) /* CTRL-D pressed */
{
done = 1;
}
else
{
i = strlen (line);
if (i > 0)
add_history (line); /* save non-empty lines */
if (NULL == code) /* nothing in code yet */
j = 0;
else
j = strlen (code);
code = realloc (code, i + j + 2);
if (NULL == code) /* out of memory */
exit (1);
if (0 == j) /* code was empty, so */
code[0] = '\0'; /* keep strncat happy */
strncat (code, line, i); /* append line to code */
code[i + j] = '\n'; /* append '\n' to code */
code[i + j + 1] = '\0';
src = Py_CompileString (code, "<stdin>", Py_single_input);
if (NULL != src) /* compiled just fine - */
{
if (ps1 == prompt || /* ">>> " or */
'\n' == code[i + j - 1]) /* "... " and double '\n' */
{ /* so execute it */
dum = PyEval_EvalCode ((PyCodeObject *)src, glb, loc);
Py_XDECREF (dum);
Py_XDECREF (src);
free (code);
code = NULL;
if (PyErr_Occurred ())
PyErr_Print ();
prompt = ps1;
}
} /* syntax error or E_EOF? */
else if (PyErr_ExceptionMatches (PyExc_SyntaxError))
{
PyErr_Fetch (&exc, &val, &trb); /* clears exception! */
if (PyArg_ParseTuple (val, "sO", &msg, &obj) &&
!strcmp (msg, "unexpected EOF while parsing")) /* E_EOF */
{
Py_XDECREF (exc);
Py_XDECREF (val);
Py_XDECREF (trb);
prompt = ps2;
}
else /* some other syntax error */
{
PyErr_Restore (exc, val, trb);
PyErr_Print ();
free (code);
code = NULL;
prompt = ps1;
}
}
else /* some non-syntax error */
{
PyErr_Print ();
free (code);
code = NULL;
prompt = ps1;
}
free (line);
}
}
Py_XDECREF(glb);
Py_XDECREF(loc);
Py_Finalize();
exit(0);
}
How do I find undefined g++ symbols __builtin_new or __pure_virtual?
-----------------------------------------------------------------------------------
To dynamically load g++ extension modules, you must recompile Python, relink it using g++ (change LINKCC in the python Modules Makefile), and link your extension module using g++ (e.g., "g++ -shared -o mymodule.so mymodule.o").
Can I create an object class with some methods implemented in C and others in Python (e.g. through inheritance)?
-----------------------------------------------------------------------------------------------------------------------------------------------------
In Python 2.2, you can inherit from builtin classes such as int, list, dict, etc.
The Boost Python Library (BPL, http://www.boost.org/libs/python/doc/index.html)
provides a way of doing this from C++ (i.e. you can inherit from an
extension class written in C++ using the BPL).
When importing module X, why do I get "undefined symbol: PyUnicodeUCS2*"?
--------------------------------------------------------------------------------------------------
You are using a version of Python that uses a 4-byte representation
for Unicode characters, but some C extension module you are importing
was compiled using a Python that uses a 2-byte representation for
Unicode characters (the default).
If instead the name of the undefined symbol starts with
``PyUnicodeUCS4``, the problem is the reverse: Python was built using
2-byte Unicode characters, and the extension module was compiled using
a Python with 4-byte Unicode characters.
This can easily occur when using pre-built extension packages. RedHat
Linux 7.x, in particular, provided a "python2" binary that is compiled
with 4-byte Unicode. This only causes the link failure if the extension
uses any of the ``PyUnicode_*()`` functions. It is also a problem if an
extension uses any of the Unicode-related format specifiers for
``Py_BuildValue`` (or similar) or parameter specifications for
``PyArg_ParseTuple()``.
You can check the size of the Unicode character a Python interpreter is
using by checking the value of sys.maxunicode::
>>> import sys
>>> if sys.maxunicode > 65535:
... print 'UCS4 build'
... else:
... print 'UCS2 build'
The only way to solve this problem is to use extension modules compiled
with a Python binary built using the same size for Unicode characters.
1
0
Here's another one of the new FAQ documents, about basic Python
programming and data types.
--amk
====================================
Programming FAQ
====================================
:Date: $Date: 2003/08/14 20:49:08 $
:Version: $Revision: 1.8 $
:Web site: http://www.python.org/
.. contents::
.. sectnum::
General Questions
===========================
Is there a source code level debugger with breakpoints, single-stepping, etc.?
-------------------------------------------------------------------------------
Yes.
The pdb module is a simple but adequate console-mode debugger for
Python. It is part of the standard Python library, and is `documented
in the Library Reference Manual
<http://www.python.org/doc/current/lib/module-pdb.html>`_. You can
also write your own debugger by using the code for pdb as an example.
The IDLE interactive development environment, which is part of the
standard Python distribution (normally available as Tools/scripts/idle),
includes a graphical debugger. There is documentation for the IDLE
debugger at http://www.python.org/idle/doc/idle2.html#Debugger
PythonWin is a Python IDE that includes a GUI debugger based on pdb.
The Pythonwin debugger colors breakpoints and has quite a few cool
features such as debugging non-Pythonwin programs. A reference
can be found at
http://www.python.org/ftp/python/pythonwin/pwindex.html More
recent versions of PythonWin are available as a part of the
ActivePython distribution (see
http://www.activestate.com/Products/ActivePython/index.html).
Pydb is a version of the standard Python debugger pdb, modified for
use with DDD (Data Display Debugger), a popular graphical debugger
front end. Pydb can be found at
http://packages.debian.org/unstable/devel/pydb.html> and DDD can be
found at http://www.gnu.org/software/ddd.
There are a number of commmercial Python IDEs that include graphical
debuggers. They include:
* Wing IDE (http://wingide.com)
* Komodo IDE (http://www.activestate.com/Products/Komodo)
Is there a tool to help find bugs or perform static analysis?
----------------------------------------------------------------------
Yes. PyChecker is a static analysis tool that finds bugs in Python
source code and warns about code complexity and style. You
can get PyChecker from http://pychecker.sf.net.
How can I create a stand-alone binary from a Python script?
-------------------------------------------------------------------
You don't need the ability to compile Python to C code, if all you
want is a stand-alone program that users can download and run without
having to install the Python distribution first. There are a number
of tools that determine the set of modules required by a program and
bind these modules together with a Python binary to produce a single
executable.
One is to use the freeze tool, which is included in the Python
source tree as ``Tools/freeze``. It converts Python byte
code to C arrays; a C compiler you can embed all
your modules into a new program, which is then linked
with the standard Python modules.
It works by scanning your source recursively for import statements (in
both forms) and looking for the modules in the standard Python path as
well as in the source directory (for built-in modules). It then turns
the bytecode for modules written in Python into C code (array
initializers that can be turned into code objects using the marshal
module) and creates a custom-made config file that only contains those
built-in modules which are actually used in the program. It then
compiles the generated C code and links it with the rest of the Python
interpreter to form a self-contained binary which acts exactly like
your script.
Obviously, freeze requires a C compiler. There are several other
utilities which don't. The first is Gordon McMillan's installer at
http://www.mcmillan-inc.com/install1.html
which works on Windows, Linux and at least some forms of Unix.
Another is Thomas Heller's py2exe (Windows only) at
http://starship.python.net/crew/theller/py2exe
A third is Christian Tismer's `SQFREEZE
<http://starship.python.net/crew/pirx>`_ which appends the byte code
to a specially-prepared Python interpreter that can find the byte
code in the executable.
A fourth is Fredrik Lundh's `Squeeze <http://www.pythonware.com/products/python/squeeze>`_.
Are there coding standards or a style guide for Python programs?
------------------------------------------------------------------------
Yes. The coding style required for standard library modules
is documented as `PEP 8 <http://www.python.org/peps/pep-0008.html>`_.
My program is too slow. How do I speed it up?
----------------------------------------------------
That's a tough one, in general. There are many tricks to speed up
Python code; consider rewriting parts in C as a last
resort.
One thing to notice is that function and (especially) method calls are
rather expensive; if you have designed a purely OO interface with lots
of tiny functions that don't do much more than get or set an instance
variable or call another method, you might consider using a more
direct way such as directly accessing instance variables. Also see the
standard module "profile" (`described in the Library Reference manual
<http://www.python.org/doc/current/lib/module-profile.html>`_) which
makes it possible to find out where your program is spending most of
its time (if you have some patience -- the profiling itself can slow
your program down by an order of magnitude).
Remember that many standard optimization heuristics you
may know from other programming experience may well apply
to Python. For example it may be faster to send output to output
devices using larger writes rather than smaller ones in order to
reduce the overhead of kernel system calls. Thus CGI scripts
that write all output in "one shot" may be faster than
those that write lots of small pieces of output.
Also, be sure to use Python's core features where appropriate.
For example, slicing allows programs to chop up
lists and other sequence objects in a single tick of the interpreter's
mainloop using highly optimized C implementations. Thus to
get the same effect as::
L2 = []
for i in range[3]:
L2.append(L1[i])
it is much shorter and far faster to use ::
L2 = list(L1[:3]) # "list" is redundant if L1 is a list.
Note that the functionally-oriented builtins such as
``map()``, ``zip()``, and friends can be a convenient
accelerator for loops that perform a single task. For example to pair the elements of two
lists together::
>>> zip([1,2,3], [4,5,6])
[(1, 4), (2, 5), (3, 6)]
or to compute a number of sines::
>>> map( math.sin, (1,2,3,4))
[0.841470984808, 0.909297426826, 0.14112000806, -0.756802495308]
The operation completes very quickly in such cases.
Other examples include the ``join()`` and ``split()``
methods of string objects. For example if s1..s7 are large (10K+) strings then
``"".join([s1,s2,s3,s4,s5,s6,s7])` may be far faster than
the more obvious ``s1+s2+s3+s4+s5+s6+s7``, since the "summation"
will compute many subexpressions, whereas ``join()`` does all the
copying in one pass. For manipulating strings, use
the ``replace()`` method on string objects. Use
regular expressions only when you're not dealing with constant string patterns.
Consider using the string formatting operations
``string % tuple`` and ``string % dictionary``.
Be sure to use the ``list.sort()`` builtin method to do sorting, and see
the `sorting mini-HOWTO <http://www.amk.ca/python/howto/sorting/XXX>`_ for examples of moderately advanced usage.
``list.sort()`` beats other techniques for sorting in all but the most
extreme circumstances.
Another common trick is to "push loops into functions or methods."
For example suppose you have a program that runs slowly and you
use the profiler to determine that a Python function ``ff()``
is being called lots of times. If you notice that ``ff ()``::
def ff(x):
...do something with x computing result...
return result
tends to be called in loops like::
list = map(ff, oldlist)
or::
for x in sequence:
value = ff(x)
...do something with value...
then you can often eliminate function call overhead by rewriting
``ff()`` to::
def ffseq(seq):
resultseq = []
for x in seq:
...do something with x computing result...
resultseq.append(result)
return resultseq
and rewrite the two examples to ``list = ffseq(oldlist)`` and to::
for value in ffseq(sequence):
...do something with value...
Single calls to ff(x) translate to ffseq([x])[0] with little
penalty. Of course this technique is not always appropriate
and there are other variants which you can figure out.
You can gain some performance by explicitly storing the results of
a function or method lookup into a local variable. A loop like::
for key in token:
dict[key] = dict.get(key, 0) + 1
resolves dict.get every iteration. If the method isn't going to
change, a slightly faster implementation is::
dict_get = dict.get # look up the method once
for key in token:
dict[key] = dict_get(key, 0) + 1
Default arguments can be used to determine values once, at
compile time instead of at run time. This can only be done for
functions or objects which will not be changed during program
execution, such as replacing ::
def degree_sin(deg):
return math.sin(deg * math.pi / 180.0)
with ::
def degree_sin(deg, factor = math.pi/180.0, sin = math.sin):
return sin(deg * factor)
Because this trick uses default arguments for terms which should
not be changed, it should only be used when you are not concerned
with presenting a possibly confusing API to your users.
Don't bother applying these optimization tricks until you know you
need them, after profiling has indicated that a particular function is
the heavily executed hot spot in the code. Optimizations almost
always make the code less clear, and you shouldn't pay the costs
of reduced clarity (increased development time, greater likelihood of bugs)
unless the resulting performance benefit is worth it.
For an anecdote related to optimization, see
http://www.python.org/doc/essays/list2str.html.
Core Language
==================
How do you set a global variable in a function?
----------------------------------------------------------
Did you do something like this? ::
x = 1 # make a global
def f():
print x # try to print the global
...
for j in range(100):
if q>3:
x=4
Any variable assigned in a function is local to that function.
unless it is specifically declared global. Since a value is bound
to ``x`` as the last statement of the function body, the compiler
assumes that ``x`` is local. Consequently the ``print x``
attempts to print an uninitialized local variable and will
trigger a ``NameError``.
The solution is to insert an explicit global declaration at the start
of the function::
def f():
global x
print x # try to print the global
...
for j in range(100):
if q>3:
x=4
In this case, all references to ``x`` are interpreted as references
to the ``x`` from the module namespace.
What are the rules for local and global variables in Python?
--------------------------------------------------------------------------
In Python, variables that are only referenced inside a function are
implicitly global. If a variable is assigned a new value anywhere
within the function's body, it's assumed to be a local. If a variable
is ever assigned a new value inside the function, the variable is
implicitly local, and you need to explicitly declare it as 'global'.
Though a bit surprising at first, a moment's consideration explains
this. On one hand, requiring ``global`` for assigned variables provides
a bar against unintended side-effects. On the other hand, if ``global``
was required for all global references, you'd be using ``global`` all the
time. You'd have to declare as global every reference to a
builtin function or to a component of an imported module. This
clutter would defeat the usefulness of the ``global`` declaration for
identifying side-effects.
How do I share global variables across modules?
------------------------------------------------
The canonical way to share information across modules within a single
program is to create a special module (often called config or cfg).
Just import the config module in all modules of your application; the
module then becomes available as a global name. Because there is only
one instance of each module, any changes made to the module object get
reflected everywhere. For example:
config.py::
x = 0 # Default value of the 'x' configuration setting
mod.py::
import config
config.x = 1
main.py::
import config
import mod
print config.x
Note that using a module is also the basis for implementing the
Singleton design pattern, for the same reason.
What are the "best practices" for using import in a module?
------------------------------------------------------------------------------
In general, don't use ``from modulename import *``.
Doing so clutters the importer's namespace. Some people avoid this idiom
even with the few modules that were designed to be imported in this
manner. Modules designed in this manner include ``Tkinter``,
``threading``, and ``wxPython``.
Import modules at the top of a file. Doing so makes it clear what
other modules your code requires and avoids questions of whether the
module name is in scope. Using one import per line makes it easy to
add and delete module imports, but using multiple imports per line
uses less screen space.
It's good practice if you import modules in the following order:
1. standard libary modules -- e.g. ``sys``, ``os``, ``getopt``, ``re``)
2. third-party library modules (anything installed in Python's
site-packages directory) -- e.g. mx.DateTime, ZODB, PIL.Image, etc.
3. locally-developed modules
Never use relative package imports. If you're writing code that's
in the ``package.sub.m1`` module and want to import ``package.sub.m2``,
do not just write ``import m2``, even though it's legal.
Write ``from package.sub import m2`` instead. Relative imports can lead to a
module being initialized twice, leading to confusing bugs.
It is sometimes necessary to move imports to a function or class to
avoid problems with circular imports. Gordon McMillan says:
Circular imports are fine where both modules use the "import <module>"
form of import. They fail when the 2nd module wants to grab a name
out of the first ("from module import name") and the import is at
the top level. That's because names in the 1st are not yet available,
because the first module is busy importing the 2nd.
In this case, if the second module is only used in one function, then the
import can easily be moved into that function. By the time the import
is called, the first module will have finished initializing, and the
second module can do its import.
It may also be necessary to move imports out of the top level of code
if some of the modules are platform-specific. In that case, it may
not even be possible to import all of the modules at the top of the
file. In this case, importing the correct modules in the
corresponding platform-specific code is a good option.
Only move imports into a local scope, such as inside a function
definition, if it's necessary to solve a problem such as avoiding a
circular import or are trying to reduce the initialization time of a
module. This technique is especially helpful if many of the imports
are unnecessary depending on how the program executes. You may also
want to move imports into a function if the modules are only ever used
in that function. Note that loading a module the first time may be
expensive because of the one time initialization of the module, but
loading a module multiple times is virtually free, costing only a couple of
dictionary lookups. Even if the module name has gone out of scope,
the module is probably available in sys.modules.
If only instances of a specific class use a module, then it is
reasonable to import the module in the class's ``__init__`` method and
then assign the module to an instance variable so that the module is
always available (via that instance variable) during the life of the
object. Note that to delay an import until the class is instantiated,
the import must be inside a method. Putting the import inside the
class but outside of any method still causes the import to occur when
the module is initialized.
How can I pass optional or keyword parameters from one function to another?
-------------------------------------------------------------------------------
Collect the arguments using the ``*`` and ``**`` specifiers in the function's
parameter list; this gives you the positional arguments as a tuple
and the keyword arguments as a dictionary. You can
then pass these arguments when calling another function by using
``*`` and ``**``::
def f(x, *tup, **kwargs):
...
kwargs['width']='14.3c'
...
g(x, *tup, **kwargs)
In the unlikely case that you care about Python
versions older than 2.0, use 'apply'::
def f(x, *tup, **kwargs):
...
kwargs['width']='14.3c'
...
apply(g, (x,)+tup, kwargs)
How do I write a function with output parameters (call by reference)?
-----------------------------------------------------------------------------
Remember that arguments are passed by assignment in Python. Since
assignment just creates references to objects, there's no alias
between an argument name in the caller and callee, and so no
call-by-reference per se. You can achieve the desired effect in a
number of ways.
1) By returning a tuple of the results::
def func2(a, b):
a = 'new-value' # a and b are local names
b = b + 1 # assigned to new objects
return a, b # return new values
x, y = 'old-value', 99
x, y = func2(x, y)
print x, y # output: new-value 100
This is almost always the clearest solution.
2) By using global variables. This isn't thread-safe, and is not
recommended.
3) By passing a mutable (changeable in-place) object::
def func1(a):
a[0] = 'new-value' # 'a' references a mutable list
a[1] = a[1] + 1 # changes a shared object
args = ['old-value', 99]
func1(args)
print args[0], args[1] # output: new-value 100
4) By passing in a dictionary that gets mutated::
def func3(args):
args['a'] = 'new-value' # args is a mutable dictionary
args['b'] = args['b'] + 1 # change it in-place
args = {'a':' old-value', 'b': 99}
func3(args)
print args['a'], args['b']
5) Or bundle up values in a class instance::
class callByRef:
def __init__(self, **args):
for (key, value) in args.items():
setattr(self, key, value)
def func4(args):
args.a = 'new-value' # args is a mutable callByRef
args.b = args.b + 1 # change object in-place
args = callByRef(a='old-value', b=99)
func4(args)
print args.a, args.b
There's almost never a good reason to get this complicated.
Your best choice is to return a tuple containing the multiple results.
How do you make a higher order function in Python?
----------------------------------------------------------
You have two choices: you can use nested scopes
or you can use callable objects. For example, suppose you wanted to
define ``linear(a,b)`` which returns a function ``f(x)`` that computes the
value ``a*x+b``. Using nested scopes::
def linear(a,b):
def result(x):
return a*x + b
return result
Or using a callable object::
class linear:
def __init__(self, a, b):
self.a, self.b = a,b
def __call__(self, x):
return self.a * x + self.b
In both cases::
taxes = linear(0.3,2)
gives a callable object where taxes(10e6) == 0.3 * 10e6 + 2.
The callable object approach has the disadvantage that it is a bit
slower and results in slightly longer code. However, note that a
collection of callables can share their signature via inheritance::
class exponential(linear):
# __init__ inherited
def __call__(self, x):
return self.a * (x ** self.b)
Object can encapsulate state for several methods::
class counter:
value = 0
def set(self, x): self.value = x
def up(self): self.value=self.value+1
def down(self): self.value=self.value-1
count = counter()
inc, dec, reset = count.up, count.down, count.set
Here ``inc()``, ``dec()`` and ``reset()`` act like functions which share the
same counting variable.
How do I copy an object in Python?
------------------------------------------
In general, try copy.copy() or copy.deepcopy() for the general case. Not all
objects can be copied, but most can.
Some objects can be copied more easily.
Dictionaries have a ``copy()`` method::
newdict = olddict.copy()
Sequences can be copied by slicing::
new_l = l[:]
How can I find the methods or attributes of an object?
--------------------------------------------------------------
For an instance x of a user-defined class, ``dir(x)`` returns an
alphabetized list of the names containing the instance attributes and
methods and attributes defined by its class.
How can my code discover the name of an object?
-------------------------------------------------------
Generally speaking, it can't, because objects don't really have
names. Essentially, assignment always binds a name to a value; The
same is true of ``def`` and ``class`` statements, but in that case the
value is a callable. Consider the following code::
class A:
pass
B = A
a = B()
b = a
print b
<__main__.A instance at 016D07CC>
print a
<__main__.A instance at 016D07CC>
Arguably the class has a name: even though it is bound to two names
and invoked through the name B the created instance is still reported
as an instance of class A. However, it is impossible to say whether
the instance's name is a or b, since both names are bound to the same
value.
Generally speaking it should not be necessary for your code to "know
the names" of particular values. Unless you are deliberately writing
introspective programs, this is usually an indication that a change of
approach might be beneficial.
In comp.lang.python, Fredrik Lundh once gave an excellent analogy in
answer to this question:
The same way as you get the name of that cat you found on your
porch: the cat (object) itself cannot tell you its name, and it
doesn't really care -- so the only way to find out what it's called
is to ask all your neighbours (namespaces) if it's their cat
(object)...
....and don't be surprised if you'll find that it's known by many
names, or no name at all!
Is there an equivalent of C's "?:" ternary operator?
----------------------------------------------------------------------
No. In many cases you can mimic a?b:c with "a and b or
c", but there's a flaw: if b is zero (or empty, or None -- anything
that tests false) then c will be selected instead. In many cases you
can prove by looking at the code that this can't happen (e.g. because
b is a constant or has a type that can never be false), but in general
this can be a problem.
Tim Peters (who wishes it was Steve Majewski) suggested the following
solution: (a and [b] or [c])[0]. Because [b] is a singleton list it
is never false, so the wrong path is never taken; then applying [0] to
the whole thing gets the b or c that you really wanted. Ugly, but it
gets you there in the rare cases where it is really inconvenient to
rewrite your code using 'if'.
The best course is usually to write a simple ``if...else`` statement.
Another solution is to implement the "?:" operator as a function::
def q(cond,on_true,on_false):
if cond:
if not isfunction(on_true): return on_true
else: return apply(on_true)
else:
if not isfunction(on_false): return on_false
else: return apply(on_false)
In most cases you'll pass b and c directly: ``q(a,b,c)``. To avoid
evaluating b or c when they shouldn't be, encapsulate them within a
lambda function, e.g.: ``q(a,lambda: b, lambda: c)``.
It has been asked *why* Python has no if-then-else expression.
There are several answers: many languages do
just fine without one; it can easily lead to less readable code;
no sufficiently "Pythonic" syntax has been discovered; a search
of the standard library found remarkably few places where using an
if-then-else expression would make the code more understandable.
In 2002, `PEP 308 <http://www.python.org/peps/pep-0308.html>`_ was
written proposing several possible syntaxes and the community was
asked to vote on the issue. The vote was inconclusive. Most people
liked one of the syntaxes, but also hated other syntaxes; many votes
implied that people preferred no ternary operator
rather than having a syntax they hated.
Is it possible to write obfuscated one-liners in Python?
----------------------------------------------------------------
Yes. Usually this is done by nesting `lambda` within `lambda`.
See the following three examples, due to Ulf Bartelt::
# Primes < 1000
print filter(None,map(lambda y:y*reduce(lambda x,y:x*y!=0,
map(lambda x,y=y:y%x,range(2,int(pow(y,0.5)+1))),1),range(2,1000)))
# First 10 Fibonacci numbers
print map(lambda x,f=lambda x,f:(x<=1) or (f(x-1,f)+f(x-2,f)): f(x,f),
range(10))
# Mandelbrot set
print (lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y,
Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,Sy=Sy,L=lambda yc,Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,i=IM,
Sx=Sx,Sy=Sy:reduce(lambda x,y:x+y,map(lambda x,xc=Ru,yc=yc,Ru=Ru,Ro=Ro,
i=i,Sx=Sx,F=lambda xc,yc,x,y,k,f=lambda xc,yc,x,y,k,f:(k<=0)or (x*x+y*y
>=4.0) or 1+f(xc,yc,x*x-y*y+xc,2.0*x*y+yc,k-1,f):f(xc,yc,x,y,k,f):chr(
64+F(Ru+x*(Ro-Ru)/Sx,yc,0,0,i)),range(Sx))):L(Iu+y*(Io-Iu)/Sy),range(Sy
))))(-2.1, 0.7, -1.2, 1.2, 30, 80, 24)
# \___ ___ \___ ___ | | |__ lines on screen
# V V | |______ columns on screen
# | | |__________ maximum of "iterations"
# | |_________________ range on y axis
# |____________________________ range on x axis
Don't try this at home, kids!
Numbers and strings
==========================
How do I specify hexadecimal and octal integers?
--------------------------------------------------------
To specify an octal digit, precede the octal value with a zero. For
example, to set the variable "a" to the octal value "10" (8 in
decimal), type::
>>> a = 010
>>> a
8
Hexadecimal is just as easy. Simply precede the hexadecimal number with a
zero, and then a lower or uppercase "x". Hexadecimal digits can be specified
in lower or uppercase. For example, in the Python interpreter::
>>> a = 0xa5
>>> a
165
>>> b = 0XB2
>>> b
178
How do I convert a string to a number?
----------------------------------------------
For integers, use the built-in ``int()`` type constructor,
e.g. int('144') == 144. Similarly, ``float()`` converts to
floating-point, e.g. ``float('144') == 144.0``.
By default, these interpret the number as decimal, so that
``int('0144') == 144`` and ``int('0x144')`` raises
``ValueError``. ``int(string, base)`` takes the base to convert from
as a second optional argument, so ``int('0x144', 16) == 324``. If the
base is specified as 0, the number is interpreted using Python's
rules: a leading '0' indicates octal, and '0x' indicates a hex number.
Do not use the built-in function ``eval()`` if all you need is to
convert strings to numbers. ``eval()`` will be significantly slower
and it presents a security risk: someone could pass you a Python
expression that might have unwanted side effects. For example,
someone could pass ``__import__('os').system("rm -rf $HOME")`` which
would erase your home directory.
``eval()`` also has the effect of interpreting numbers as Python
expressions, so that e.g. eval('09') gives a syntax error because Python
regards numbers starting with '0' as octal (base 8).
How do I convert a number to a string?
----------------------------------------------
To convert, e.g., the number 144 to the string '144', use the built-in
function ``str()``. If you want a hexadecimal or octal
representation, use the built-in functions ``hex()`` or ``oct()``.
For fancy formatting, use `the % operator <http://www.python.org/doc/lib/typesseq-strings.html>`_ on strings, e.g. ``"%04d" % 144``
yields '0144' and ``"%.3f" % (1/3.0)`` yields '0.333'. See the library
reference manual for details.
How do I modify a string in place?
------------------------------------------
You can't, because strings are immutable. If you need an object with
this ability, try converting the string to a list or use the array
module::
>>> s = "Hello, world"
>>> a = list(s)
>>> print a
['H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd']
>>> a[7:] = list("there!")
>>> ''.join(a)
'Hello, there!'
>>> import array
>>> a = array.array('c', s)
>>> print a
array('c', 'Hello, world')
>>> a[0] = 'y' ; print a
array('c', 'yello world')
>>> a.tostring()
'yello, world'
How do I use strings to call functions/methods?
----------------------------------------------------------
There are various techniques.
* The best is to use a dictionary that maps strings to functions. The
primary advantage of this technique is that the strings do not need
to match the names of the functions. This is also the primary
technique used to emulate a case construct::
def a():
pass
def b():
pass
dispatch = {'go': a, 'stop': b} # Note lack of parens for funcs
dispatch[get_input()]() # Note trailing parens to call function
* Use the built-in function ``getattr()``::
import foo
getattr(foo, 'bar')()
Note that getattr() works on any object, including classes, class
instances, modules, and so on.
This is used in several places in the standard library, like
this::
class Foo:
def do_foo(self):
...
def do_bar(self):
...
f = getattr(foo_instance, 'do_' + opname)
f()
* Use ``locals()`` or ``eval()`` to resolve the function name::
def myFunc():
print "hello"
fname = "myFunc"
f = locals()[fname]
f()
f = eval(fname)
f()
Note: Using ``eval()`` is slow and dangerous. If you don't have absolute control
over the contents of the string, someone could pass a string that
resulted in an arbitrary function being executed.
Is there an equivalent to Perl's chomp() for removing trailing newlines from strings?
--------------------------------------------------------------------------------------------
There are two partial substitutes. If you want to remove all trailing
whitespace, use the ``rstrip()`` method of string objects. This removes all trailing whitespace, not just a single newline.
Otherwise, if there is only one line in the string ``S``, use
``S.splitlines()[0]``.
Is there a scanf() or sscanf() equivalent?
--------------------------------------------------
Not as such.
For simple input parsing, the easiest approach is usually to split the
line into whitespace-delimited words using the ``split()`` method of
string objects and then convert decimal strings to numeric values using
``int()`` or ``float()``. ``split()`` supports an optional "sep"
parameter which is useful if the line uses something other than
whitespace as a separator.
For more complicated input parsing, regular expressions
more powerful than C's ``sscanf()`` and better suited for the task.
What does 'UnicodeError: ASCII [decoding,encoding] error: ordinal not in range(128)' mean?
-----------------------------------------------------------------------------------------------------
This error indicates that your Python installation can handle
only 7-bit ASCII strings. There are a couple ways to fix or
work around the problem.
If your programs must handle data in arbitary character set encodings,
the environment the application runs in will generally identify the
encoding of the data it is handing you. You need to convert the input
to Unicode data using that encoding. For example, a program that
handles email or web input will typically find character set encoding
information in Content-Type headers. This can then be used to
properly convert input data to Unicode. Assuming the string referred
to by ``value`` is encoded as UTF-8::
value = unicode(value, "utf-8")
will return a Unicode object. If the data is not correctly encoded as
UTF-8, the above call will raise a ``UnicodeError`` exception.
If you only want strings coverted to Unicode which have non-ASCII
data, you can try converting them first assuming an ASCII encoding,
and then generate Unicode objects if that fails::
try:
x = unicode(value, "ascii")
except UnicodeError:
value = unicode(value, "utf-8")
else:
# value was valid ASCII data
pass
It's possible to set a default encoding in a file called ``sitecustomize.py``
that's part of the Python library. However, this isn't recommended because changing the Python-wide default encoding may cause third-party extension modules to fail.
Note that on Windows, there is an encoding known as "mbcs", which uses
an encoding specific to your current locale. In many cases, and
particularly when working with COM, this may be an appropriate default
encoding to use.
Sequences (Tuples/Lists)
=================================
How do I convert between tuples and lists?
------------------------------------------------
The function ``tuple(seq)`` converts any sequence (actually, any
iterable) into a tuple with the same items in the same order.
For example, ``tuple([1, 2, 3])`` yields ``(1, 2, 3)`` and ``tuple('abc')``
yields ``('a', 'b', 'c')``. If the argument is
a tuple, it does not make a copy but returns the same object, so
it is cheap to call ``tuple()`` when you aren't sure that an object
is already a tuple.
The function ``list(seq)`` converts any sequence or iterable into a list with
the same items in the same order.
For example, ``list((1, 2, 3))`` yields ``[1, 2, 3]`` and ``list('abc')``
yields ``['a', 'b', 'c']``. If the argument is a list,
it makes a copy just like ``seq[:]`` would.
What's a negative index?
--------------------------------------------------------------------
Python sequences are indexed with positive numbers and
negative numbers. For positive numbers 0 is the first index
1 is the second index and so forth. For negative indices -1
is the last index and -2 is the pentultimate (next to last) index
and so forth. Think of ``seq[-n]`` as the same as ``seq[len(seq)-n]``.
Using negative indices can be very convenient. For example ``S[:-1]``
is all of the string except for its last character, which is useful
for removing the trailing newline from a string.
How do I iterate over a sequence in reverse order?
---------------------------------------------------------
If it is a list, the fastest solution is ::
list.reverse()
try:
for x in list:
"do something with x"
finally:
list.reverse()
This has the disadvantage that while you are in the loop, the list
is temporarily reversed. If you don't like this, you can make a copy.
This appears expensive but is actually faster than other solutions::
rev = list[:]
rev.reverse()
for x in rev:
<do something with x>
If it's not a list, a more general but slower solution is::
for i in range(len(sequence)-1, -1, -1):
x = sequence[i]
<do something with x>
A more elegant solution, is to define a class which acts as a sequence
and yields the elements in reverse order (solution due to Steve
Majewski)::
class Rev:
def __init__(self, seq):
self.forw = seq
def __len__(self):
return len(self.forw)
def __getitem__(self, i):
return self.forw[-(i + 1)]
You can now simply write::
for x in Rev(list):
<do something with x>
Unfortunately, this solution is slowest of all, due to the method
call overhead.
How do you remove duplicates from a list?
-------------------------------------------------
See the Python Cookbook for a long discussion of many ways to do this:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52560
If you don't mind reordering the list, sort it and then scan from the
end of the list, deleting duplicates as you go::
if List:
List.sort()
last = List[-1]
for i in range(len(List)-2, -1, -1):
if last==List[i]: del List[i]
else: last=List[i]
If all elements of the list may be used as
dictionary keys (i.e. they are all hashable)
this is often faster ::
d = {}
for x in List: d[x]=x
List = d.values()
How do you make an array in Python?
----------------------------------------------------
Use a list::
["this", 1, "is", "an", "array"]
Lists are equivalent to C or Pascal arrays in their time complexity;
the primary difference is that a Python list can contain objects of
many different types.
The ``array`` module also provides methods for creating arrays of
fixed types with compact representations, but they are slower to index
than lists. Also note that the Numeric extensions and others define
array-like structures with various characteristics as well.
To get Lisp-style linked lists, you can emulate cons cells using tuples::
lisp_list = ("like", ("this", ("example", None) ) )
If mutability is desired, you could use lists instead of tuples. Here
the analogue of lisp car is ``lisp_list[0]`` and the analogue of cdr
is ``lisp_list[1]``. Only do this if you're sure you really need to,
because it's usually a lot slower than using Python lists.
How do I create a multidimensional list?
---------------------------------------------------------------
You probably tried to make a multidimensional array like this::
A = [[None] * 2] * 3
This looks correct if you print it::
>>> A
[[None, None], [None, None], [None, None]]
But when you assign a value, it shows up in multiple places:
>>> A[0][0] = 5
>>> A
[[5, None], [5, None], [5, None]]
The reason is that replicating a list with ``*`` doesn't create copies, it only creates references to the existing objects. The ``*3``
creates a list containing 3 references to the same list of length
two. Changes to one row will show in all rows, which is almost certainly
not what you want.
The suggested approach is to create a list of the desired length first
and then fill in each element with a newly created list::
A = [None]*3
for i in range(3):
A[i] = [None] * 2
This generates a list containing 3 different lists of length two.
You can also use a list comprehension::
w,h = 2,3
A = [ [None]*w for i in range(h) ]
Or, you can use an extension that provides a matrix datatype; `Numeric
Python <XXX>`_ is the best known.
How do I apply a method to a sequence of objects?
--------------------------------------------------------------------------
Use a list comprehension::
result = [obj.method() for obj in List]
More generically, you can try the following function::
def method_map(objects, method, arguments):
"""method_map([a,b], "meth", (1,2)) gives [a.meth(1,2), b.meth(1,2)]"""
nobjects = len(objects)
methods = map(getattr, objects, [method]*nobjects)
return map(apply, methods, [arguments]*nobjects)
Dictionaries
==================
How can I get a dictionary to display its keys in a consistent order?
-----------------------------------------------------------------------------
You can't. Dictionaries store their keys in an unpredictable order,
so the display order of a dictionary's elements will be similarly
unpredictable.
This can be frustrating if you want to save a printable version to a
file, make some changes and then compare it with some other printed
dictionary. In this case, use the ``pprint`` module to pretty-print
the dictionary; the items will be presented in order sorted by the key.
A more complicated solution is to subclass ``UserDict.UserDict``
to create a ``SortedDict`` class that prints itself in a predictable order.
Here's one simpleminded implementation of such a class::
import UserDict, string
class SortedDict(UserDict.UserDict):
def __repr__(self):
result = []
append = result.append
keys = self.data.keys()
keys.sort()
for k in keys:
append("%s: %s" % (`k`, `self.data[k]`))
return "{%s}" % string.join(result, ", ")
___str__ = __repr__
This will work for many common situations you might encounter, though
it's far from a perfect solution. The largest flaw is that if some
values in the dictionary are also dictionaries, their values won't be
presented in any particular order.
I want to do a complicated sort: can you do a Schwartzian Transform in Python?
--------------------------------------------------------------------------------------
Yes, it's quite simple with list comprehensions.
The technique, attributed to Randal Schwartz of the Perl community,
sorts the elements of a list by a metric which maps each element to
its "sort value". To sort a list of strings by their uppercase
values::
tmp1 = [ (x.upper(), x) for x in L ] # Schwartzian transform
tmp1.sort()
Usorted = [ x[1] for x in tmp1 ]
To sort by the integer value of a subfield extending from positions 10-15
in each string::
tmp2 = [ (int(s[10:15]), s) for s in L ] # Schwartzian transform
tmp2.sort()
Isorted = [ x[1] for x in tmp2 ]
Note that Isorted may also be computed by ::
def intfield(s):
return int(s[10:15])
def Icmp(s1, s2):
return cmp(intfield(s1), intfield(s2))
Isorted = L[:]
Isorted.sort(Icmp)
but since this method calls ``intfield()`` many times for each element
of L, it is slower than the Schwartzian Transform.
How can I sort one list by values from another list?
------------------------------------------------------------
Merge them into a single list of tuples, sort the resulting list,
and then pick out the element you want. ::
>>> list1 = ["what", "I'm", "sorting", "by"]
>>> list2 = ["something", "else", "to", "sort"]
>>> pairs = zip(list1, list2)
>>> pairs
[('what', 'something'), ("I'm", 'else'), ('sorting', 'to'), ('by', 'sort')]
>>> pairs.sort()
>>> result = [ x[1] for x in pairs ]
>>> result
['else', 'sort', 'to', 'something']
An alternative for the last step is::
result = []
for p in pairs: result.append(p[1])
If you find this more legible, you might prefer to use this instead of
the final list comprehension. However, it is almost twice as slow for
long lists. Why? First, the ``append()`` operation has to reallocate
memory, and while it uses some tricks to avoid doing that each time,
it still has to do it occasionally, and that costs quite a bit.
Second, the expression "result.append" requires an extra attribute
lookup, and third, there's a speed reduction from having to make
all those function calls.
Objects
=============
What is a class?
------------------------
A class is the particular object type created by executing
a class statement. Class objects are used as templates to create
instance objects, which embody both the data
(attributes) and code (methods) specific to a datatype.
A class can be based on one or more other classes, called its base
class(es). It then inherits the attributes and methods of its base
classes. This allows an object model to be successively refined by
inheritance. You might have a generic ``Mailbox`` class that provides
basic accessor methods for a mailbox, and subclasses such as
``MboxMailbox``, ``MaildirMailbox``, ``OutlookMailbox`` that handle
various specific mailbox formats.
What is a method?
-------------------------
A method is a function on some object ``x`` that you normally call as
``x.name(arguments...)``. Methods are defined as functions inside the
class definition::
class C:
def meth (self, arg):
return arg*2 + self.attribute
What is self?
---------------------
Self is merely a conventional name for the first argument of a method.
A method defined as ``meth(self, a, b, c)`` should be called as
``x.meth(a, b, c)`` for some instance ``x`` of the class in which the
definition occurs; the called method will think it is called as
``meth(x, a, b, c)``.
How do I check if an object is an instance of a given class or of a subclass of it?
-------------------------------------------------------------------------------------------
Use the built-in function ``isinstance(obj, cls)``. You can check if
an object is an instance of any of a number of classes by providing a tuple instead of a single class, e.g. ``isinstance(obj, (class1, class2, ...))``,
and can also check whether an object is one of Python's built-in types, e.g.
``isinstance(obj, str)`` or ``isinstance(obj, (int, long, float, complex))``.
Note that most programs do not use ``isinstance()`` on user-defined
classes very often. If you are developing the classes yourself, a
more proper object-oriented style is to define methods on the classes
that encapsulate a particular behaviour, instead of checking the
object's class and doing a different thing based on what class it is.
For example, if you have a function that does something::
def search (obj):
if isinstance(obj, Mailbox):
# ... code to search a mailbox
elif isinstance(obj, Document):
# ... code to search a document
elif ...
A better approach is to define a ``search()`` method on all the
classes and just call it::
class Mailbox:
def search(self):
# ... code to search a mailbox
class Document:
def search(self):
# ... code to search a document
obj.search()
What is delegation?
---------------------------
Delegation is an object oriented technique (also called a design
pattern). Let's say you have an object ``x`` and want to change the
behaviour of just one of its methods. You can create a new class that
provides a new implementation of the method you're interested in changing
and delegates all other methods to the corresponding method of ``x``.
Python programmers can easily implement delegation. For example, the
following class implements a class that behaves like a file but
converts all written data to uppercase::
class UpperOut:
def __init__(self, outfile):
self.__outfile = outfile
def write(self, s):
self.__outfile.write(s.upper())
def __getattr__(self, name):
return getattr(self.__outfile, name)
Here the ``UpperOut`` class redefines the ``write()`` method to
convert the argument string to uppercase before calling the underlying
``self.__outfile.write()`` method. All other methods are delegated to
the underlying ``self.__outfile`` object. The delegation is
accomplished via the ``__getattr__`` method; consult `the language
reference <http://www.python.org/doc/ref/attribute-access.html>`_ for
more information about controlling attribute access.
Note that for more general cases delegation can get trickier. When
attributes must be set as well as retrieved, the class must define a
``__settattr__`` method too, and it must do so carefully. The basic
implementation of __setattr__ is roughly equivalent to the following::
class X:
...
def __setattr__(self, name, value):
self.__dict__[name] = value
...
Most __setattr__ implementations must modify
self.__dict__ to store local state for self without
causing an infinite recursion.
How do I call a method defined in a base class from a derived class that overrides it?
----------------------------------------------------------------------------------------------
If you're using new-style classes, use the built-in ``super()`` function::
class Derived(Base):
def meth (self):
super(Derived, self).meth()
If you're using classic classes: For a class definition such as
``class Derived(Base): ...`` you can call method ``meth()`` defined in
``Base`` (or one of ``Base``'s base classes) as ``Base.meth(self,
arguments...)``. Here, ``Base.meth`` is an unbound method, so you
need to provide the ``self`` argument.
How can I organize my code to make it easier to change the base class?
------------------------------------------------------------------------------
You could define an alias for the base class, assign the real base
class to it before your class definition, and use the alias throughout
your class. Then all you have to change is the value assigned to the
alias. Incidentally, this trick is also handy if you want to decide
dynamically (e.g. depending on availability of resources) which base
class to use. Example::
BaseAlias = <real base class>
class Derived(BaseAlias):
def meth(self):
BaseAlias.meth(self)
...
How do I create static class data and static class methods?
-------------------------------------------------------------------
Static data (in the sense of C++ or Java) is easy; static methods
(again in the sense of C++ or Java) are not supported directly.
For static data, simply define a class attribute. To assign a new
value to the attribute, you have to explicitly use the class name in
the assignment::
class C:
count = 0 # number of times C.__init__ called
def __init__(self):
C.count = C.count + 1
def getcount(self):
return C.count # or return self.count
``c.count`` also refers to ``C.count`` for any ``c`` such that
``isinstance(c, C)`` holds, unless overridden by ``c`` itself or by some
class on the base-class search path from ``c.__class__`` back to ``C``.
Caution: within a method of C, an assignment like ``self.count = 42``
creates a new and unrelated instance vrbl named "count" in ``self``'s own dict.
Rebinding of a class-static data name must always specify the class
whether inside a method or not::
C.count = 314
Static methods are possible when you're using new-style classes::
class C:
def static(arg1, arg2, arg3):
# No 'self' parameter!
...
static = staticmethod(static)
However, a far more straightforward way to get the effect of a static
method is via a simple module-level function::
def getcount():
return C.count
If your code is structured so as to define one class (or tightly
related class hierarchy) per module, this supplies the desired
encapsulation.
How can I overload constructors (or methods) in Python?
---------------------------------------------------------------
This answer actually applies to all methods, but the question
usually comes up first in the context of constructors.
In C++ you'd write ::
class C {
C() { cout << "No arguments\n"; }
C(int i) { cout << "Argument is " << i << "\n"; }
}
in Python you have to write a single constructor that catches all
cases using default arguments. For example::
class C:
def __init__(self, i=None):
if i is None:
print "No arguments"
else:
print "Argument is", i
This is not entirely equivalent, but close enough in practice.
You could also try a variable-length argument list, e.g. ::
def __init__(self, *args):
....
The same approach works for all method definitions.
I try to use __spam and I get an error about _SomeClassName__spam.
--------------------------------------------------------------------------
Variables with double leading underscore are "mangled" to provide a
simple but effective way to define class private variables. Any
identifier of the form ``__spam`` (at least two leading
underscores, at most one trailing underscore) is textually
replaced with ``_classname__spam``, where ``classname`` is the
current class name with any leading underscores stripped.
This doesn't guarantee privacy: an outside user can still deliberately
access the "_classname__spam" attribute, and private values are visible
in the object's ``__dict__``. Many Python programmers never bother to use
private variable names at all.
My class defines __del__ but it is not called when I delete the object.
-------------------------------------------------------------------------------
There are several possible reasons for this.
The del statement does not necessarily call __del__ -- it simply
decrements the object's reference count, and if this reaches zero
__del__ is called.
If your data structures contain circular links (e.g. a tree where each
child has a parent reference and each parent has a list of children)
the reference counts will never go back to zero. Once in a while
Python runs an algorithm to detect such cycles, but the garbage
collector might run some time after the last reference to your data
structure vanishes, so your __del__ method may be called at an
inconvenient and random time. This is inconvenient if you're trying to
reproduce a problem. Worse, the order in which object's __del__
methods are executed is arbitrary. You can run ``gc.collect()`` to
force a collection, but there *are* pathological cases where objects will
never be collected.
Despite the cycle collector, it's still a good idea to define an
explicit ``close()`` method on objects to be called whenever you're
done with them. The ``close()`` method can then remove attributes
that refer to subobjecs. Don't call ``__del__`` directly --
``__del__`` should call ``close()`` and ``close()`` should make sure
that it can be called more than once for the same object.
Another way to avoid cyclical references is to use the "weakref"
module, which allows you to point to objects without incrementing
their reference count. Tree data structures, for instance, should use
weak references for their parent and sibling references (if they need
them!).
If the object has ever been a local variable in a function that caught
an expression in an except clause, chances are that a reference to the
object still exists in that function's stack frame as contained in the
stack trace. Normally, calling ``sys.exc_clear()`` will take care of
this by clearing the last recorded exception.
Finally, if your __del__ method raises an exception, a warning message
is printed to sys.stderr.
How do I get a list of all instances of a given class?
--------------------------------------------------------------
Python does not keep track of all instances of a class (or of a
built-in type). You can program the class's constructor to keep track
of all instances by keeping a list of weak references to each
instance.
Modules
=============
How do I create a .pyc file?
-------------------------------------
When a module is imported for the first time (or when the source is
more recent than the current compiled file) a ``.pyc`` file containing
the compiled code should be created in the same directory as the
``.py`` file.
One reason that a ``.pyc`` file may not be created is permissions
problems with the directory. This can happen, for example, if you
develop as one user but run as another, such as if you are testing
with a web server. Creation of a .pyc file is automatic if you're
importing a module and Python has the ability (permissions, free
space, etc...) to write the compiled module back to the directory.
Running Python on a top level script is not considered an import and
no ``.pyc`` will be created. For example, if you have a top-level
module ``abc.py`` that imports another module ``xyz.py``, when you run
abc, ``xyz.pyc`` will be created since xyz is imported, but no
``abc.pyc`` file will be created since ``abc.py`` isn't being
imported.
If you need to create abc.pyc -- that is, to create a .pyc file for a
module that is not imported -- you can, using the py_compile and
compileall modules.
The ``py_compile`` module can manually compile any module. One way is
to use the ``compile()`` function in that module interactively::
>>> import py_compile
>>> py_compile.compile('abc.py')
This will write the ``.pyc`` to the same location as ``abc.py`` (or
you can override that with the optional parameter ``cfile``).
You can also automatically compile all files in a directory or
directories using the ``compileall`` module.
You can do it from the shell prompt by running ``compileall.py``
and providing the path of a directory containing Python files to compile::
python compileall.py .
How do I find the current module name?
---------------------------------------------
A module can find out its own module name by looking at the predefined
global variable ``__name__``. If this has the value '__main__', the
program is running as a script. Many modules that are usually used by
importing them also provide a command-line interface or a self-test,
and only execute this code after checking ``__name__``::
def main():
print 'Running test...'
...
if __name__ == '__main__':
main()
How can I have modules that mutually import each other?
---------------------------------------------------------------
Suppose you have the following modules:
foo.py::
from bar import bar_var
foo_var=1
bar.py::
from foo import foo_var
bar_var=2
The problem is that the interpreter will perform the following steps:
* main imports foo
* Empty globals for foo are created
* foo is compiled and starts executing
* foo imports bar
* Empty globals for bar are created
* bar is compiled and starts executing
* bar imports foo (which is a no-op since there already is a module named foo)
* bar.foo_var = foo.foo_var
The last step fails, because Python isn't done with interpreting ``foo``
yet and the global symbol dictionary for ``foo`` is still empty.
The same thing happens when you use ``import foo``, and then try to
access ``foo.foo_var`` in global code.
There are (at least) three possible workarounds for this problem.
Guido van Rossum recommends avoiding all uses of ``from <module>
import ...``, and placing all code inside functions. Initializations
of global variables and class variables should use constants or
built-in functions only. This means everything from an imported
module is referenced as ``<module>.<name>``.
Jim Roskind suggests performing steps in the following order in each
module:
* exports (globals, functions, and classes that don't need imported base classes)
* ``import`` statements
* active code (including globals that are initialized from imported values).
van Rossum doesn't like this approach much because the imports
appear in a strange place, but it does work.
Matthias Urlichs recommends restructuring your code so that the
recursive import is not necessary in the first place.
These solutions are not mutually exclusive.
__import__('x.y.z') returns <module 'x'>; how do I get z?
-----------------------------------------------------------------------
Try::
__import__('x.y.z').y.z
For more realistic situations, you may have to do something like ::
m = __import__(s)
for i in s.split(".")[1:]:
m = getattr(m, i)
When I edit an imported module and reimport it, the changes don't show up. Why does this happen?
--------------------------------------------------------------------------------------------------------------------------------------------
For reasons of efficiency as well as consistency, Python only reads
the module file on the first time a module is imported. If it didn't,
in a program consisting of many modules where each one imports the
same basic module, the basic module would be parsed and re-parsed many
times. To force rereading of a changed module, do this::
import modname
reload(modname)
Warning: this technique is not 100% fool-proof. In particular,
modules containing statements like ::
from modname import some_objects
will continue to work with the old version of the imported objects.
If the module contains class definitions, existing class instances
will *not* be updated to use the new class definition. This can
result in the following paradoxical behaviour::
>>> import cls
>>> c = cls.C() # Create an instance of C
>>> reload(cls)
<module 'cls' from 'cls.pyc'>
>>> isinstance(c, cls.C) # isinstance is false?!?
False
The nature of the problem is made clear if you print out the class objects:
>>> c.__class__
<class cls.C at 0x7352a0>
>>> cls.C
<class cls.C at 0x4198d0>
1
0
KirbyBase 1.3 is now available at:
http://www.netpromi.com/files/KirbyBase-1.3.zip
What is KirbyBase?
KirbyBase is a simple, pure-Python, plain-text, flat-file database
management system that can be used either embedded in your application
or in a client/server, multi-user mode.
To find out more about KirbyBase, go to:
http://www.netpromi.com/kirbybase.html
Changes:
Added ability to pass field values to update and insert using a dictionary.
Added ability to specify field to sort on and sort direction for the
results of a select.
Added len method.
Fixed bug in validateMatchCriteria where script was not restricting
other match criteria if already attempting to match by recno.
Fixed bug in validateMatchCriteria where script was not checking to see
if pattern argument was an integer when attempting to match by recno.
Changed the way field types are handled internally. This should not
change any of the api or interfaces, EXCEPT for the getFieldTypes
method, which now returns a list of types, instead of a list of strings.
I hope this doesn't screw anyone's programs up.
Corrected version number to conform to guidelines in distutils
documentation.
1
0