One word: inspect.
The inspect module provides several useful functions to help get information about live objects such as modules, classes, methods, functions, tracebacks, frame objects, and code objects. For example, it can help you examine the contents of a class, retrieve the source code of a method, extract and format the argument list for a function, or get all the information you need to display a detailed traceback.
It's in the standard library, and the docs have examples. So, you just print(inspect.getsource(os))
, or do inspect.getsourcefile(os)
, etc.
Note that some of the standard-library modules are written in C (or are even fake modules built into the interpreter), in which case getsourcefile
returns nothing, but getfile
will at least tell you it's a .so
/.pyd
/whatever, which you can use to look up the original C source in, say, a copy of the Python source code.
You can also just type help(os)
, and the FILE
right at the top gives you the path (generally the same as getsourcefile
for Python modules, the same a getfile
otherwise).
And you can always go to the online source for the Python modules and C extension modules. Just change the "2.7" to "3.3", etc., in the URL to get different versions. (I believe if you remove the version entirely, you get the trunk code, currently corresponding to 3.4 pre-alpha, but don't quote me on that.)
The os.listdir
function isn't actually defined directly in os
; it's effectively from <platform-specific-module> import *
imported. You can trace it down through a few steps yourself, but it's usually going to be posix_listdir
in posixmodule.c
on most platforms. (Even Windows—recent versions use the same file to define the posix
module on non-Windows, and the nt
and posix
modules on Windows, and there's a bunch of #if defined(…)
stuff in the code.)