(An Unofficial) Python FAQ Wiki

putting the community back in "maintained by the community"

Suggestions

Post suggestions for new articles as comments to this page. If you can, format your suggestion as an article stub, so the administrators can just cut and paste when creating the actual article page. Complete articles are of course even better. For some tips on formatting, see the example on this page.

If you have other suggestions, feel free to post them here as well.

Note: Suggestions for the Tutor FAQ should be posted to this page.

Note: To cut down on spamming, you currently need to be logged in before you can post comments. To log in (and sign up, if necessary), click on the "log in" link in the upper right corner.

Comments

The "Python's Design" questions should probably be broken out into a FAQ of their own.

The index scripts support arbitrary categories (and also multiple categories for each article), so in theory, all you need to do is to simply change the category for the relevant articles.

But that assumes that we'll use this site for more than just collecting comments to use when updating the python.org FAQ, of course. Should we move FAQ maintenance over to this wiki? I've set up a separate page for that discussion.

How about a section for a Tutorial FAQ? It could feature some of the more common questions from the tutor mailing list (like "How do I write a program to print a word backwards?"). I'm sure Alan and Kent would be happy for their more common answers to be used as articles.

update: see this page for details on this subproject

How do I print to a Windows printer?

Posted to how-do-i-print-to-a-windows-printer

How do I watch a directory for changes on Windows?

Posted to how-do-i-watch-a-directory-for-changes-on-windows

How do I copy a file on Windows?

Posted to how-do-i-copy-a-file-on-windows

Why doesn't Python release the memory when I delete a large object?

(this is an article stub)

Python has probably released the memory, but Python's memory allocator doesn't necessarily return the memory to the operating system, so it may look as if the Python process uses a lot more virtual memory than it actually uses.

(add more memory allocation details here)

Another possible cause is that Python uses so-called "free lists" for certain object types, including integers and floats. Tim Peters writes:

If I do

>>> L = range(50*1024*100)
>>> del L

Python is still using more than 60 MB. Why isn't the memory released?

It's that you've created 5 million integers simultaneously alive, and each int object consumes 12 bytes. "For speed", Python maintains an internal free list for integer objects. Unfortunately, that free list is both immortal and unbounded in size. floats also use an immortal & unbounded free list.

"For speed", Python maintains an internal free list for integer objects. Unfortunately, that free list is both immortal and unbounded in size. floats also use an immortal & unbounded free list.

/.../ Do you really need a list containing 5 million integers? I never do ;-) Something like

for i in xrange(50*1024*100):  # note the "x" in "xrange"
    whatever

consumes a trivial amount of memory, because only two integers in the range are simultaneously alive at any point, and the free list makes reusing their space fast.

Q. Anyone have any good advice to someone interested in learning about innards of Python implementation?

Neal Norwitz writes:

There are only a handful of top level directories that are interesting:

  • Include - include files
  • Objects - all Python objects (list, dict, int, float, functions, and many others)
  • Python - core interpreter and other support facilities
  • Lib - Python stdlib (Lib/test is the test suite)
  • Modules - C extension modules
  • Parser - simple parser/tokenizer

The last three probably aren't interesting. However, if you are interested in the GC (or SRE) implementation, then you should look under Modules as gcmodule.c and _sre.c are there. So are a bunch of others.

Include/ isn't particularly interesting. Objects/ isn't too interesting either from the standpoint of learning about the interpreter. Although the object implementations may be interesting in their own right. Each object is in an unsurprising file named something like: listobject.c or intobject.c.

That leaves Python/ which is where the real innards are. If you are interested in the interpreter, then Python/ceval.c is pretty much it. The compiler is primarly in Python/compile.c, but also see Python/ast.c (2.5 only) and Python/symtable.c. All the global builtin functions are in Python/bltinmodule.c. Import support is in Python/import.c. Most of the other files in Python/ are small and/or platform specific. They probably aren't as interesting in general.

Suggested FAQ:

Q: How can I reverse a string, an array, a list, etc.?

A:

Step a slice backwards (allowed for strings and lists and tuples since Python 2.3.5):

    def reverse(chars):
            return chars[::-1]

Or convert to array and reverse that:

    def reverse(chars):
            aa = array.array('c', chars)
            aa.reverse()
            return aa.tostring()

Or step thru the elements yourself:

    def reverse(chars):
            ochars = ''
            beyond = len(chars)
            for ix in range(beyond):
                    ochars += chars[beyond - 1 - ix]
            return ochars

Q: How can I accept quoted strings and numbers as input, without accidentally also accepting OS commands as input?

A: eval(source, {'builtins': {}})

Note: What eval may do to you remains as surprising as ever if you mistype this idiom as: eval(source, {})

Note: This idiom will also accept simple literal combinations of input, such as '1+2'.

Q: How can I accept quoted strings and numbers as input, without accidentally also accepting OS commands as input?

A: eval(source, {'builtins': {}})

Note: What eval may do to you remains as surprising as ever if you mistype this idiom as: eval(source, {})

Note: This idiom will also accept simple literal combinations of input, such as '1+2'.

Sorry for the stutter. After those two duplicate wrong tries, here's a third, hopefully better:

Q: How can I tell Python to calculate what quoted strings and numbers mean, without also accidentally accepting OS commands as input?

A: eval(source, {'builtins': {}})

Note: What eval may do to you remains as surprising as ever if you mistype this idiom as: eval(source, {})

Note: This idiom makes sense of ordinary Python literals (such as 010, 0x8, 8.125e+0, and "\x45ight"). This idiom also correctly interprets simple literal expressions, such as 64**0.5.

c_void = None is not doc'ed, but is suggested by:

ctypes.POINTER(None) <class 'ctypes.cvoidp'>

cvoid = cint often works, but if you say a restype is c_int, then doctest's of that call will print an int. If you say restype is None, then they don't, which is more like what you mean.

P.S. The Q for that A might be: How do I declare that CTypes function returns void?

P.P.S. The Python session I tried to quote there before the Wiki input syntax interfered was more like:

))) ctypes.POINTER(None) (class 'ctypes.cvoidp') )))

Maybe you get what I mean. My input to Python was: ctypes.POINTER(None)

Next Q: How do I declare that a CTypes function returns unsigned char?

A: cuchar = ctypes.cubyte

This actually is doc'ed, it's just annoying.