views:

66

answers:

4

This is a bit of a random question that is more out of curiosity than any specific need.

Is it possible to write some python code that will print some stuff out, including the source code itself, without having the python code stored in a file? For example, doing something like this at the Bash prompt:

$ echo '
> print "The Code:"
> PrintScript() # What would this function look like?
> for i in range(5):
>     print i,
> print "!"
> ' | python

and get an output like this:

The Code:
print "The Code:"
PrintScript() # What would this function look like?
for i in range(5):
    print i,
print "!"
0 1 2 3 4 5 !

I suspect that this probably can't be done, but given python's introspection capabilities, I was curious to know whether it extended to this level.

+1  A: 
Tamás
This only works if your code is in a file, not if the code is passed in through stdin or `python -c <command>`.
Wim
I tried this (on Cygwin under Windows and Linux) and both just produced an exception: `IOError: [Errno 2] No such file or directory: '<stdin>'`
Al
You *can* read from `sys.stdin`, but the interpreter already read and compiled all your code on startup, so you won't be able to get it this way.
Wim
Thanks, you're right, I wasn't careful enough, Answer modified.
Tamás
+2  A: 

That's the closest I'm getting:

echo 'import  __main__,inspect;print inspect.getsource(__main__)' | python

which fails... In any case, the original code is eaten up (read from stdin) by the interpreter at startup. At most you may be able to get to the compiled code, again through the __main__ module.

Update:

The dis module is supposed to give you a disassembly of all functions in a module, but even that one isn't seeing any code:

$ echo -e 'import  __main__,dis;print dis.dis(__main__)' | python
None

And even when I throw in a function:

$ echo -e "import  __main__,dis;print dis.dis(__main__)\ndef x():\n pass" | python
None
Wim
A: 

Yes, it is indeed possible to write a program which outputs it's own source. You don't need even introspection for this tasks, you just need to be able to print computed strings (works with every language).

The technique is called Quine and here is a rather short example in Python:

quine = 'quine = %r\r\nprint quine %% quine'
print quine % quine

But quines aren't limited to such simple programs. They can do much more, for example printing their own source backwards and so on... :)

tux21b
+1  A: 

closest you can get is using readline to interrogate the command history if available from what i can see e.g. but i suspect this may not contain stuff piped into the session and would only work for interactive sessions anyway

jk