Python script that prints its source - python

Is it possible (not necessarly using python introspection) to print the source code of a script?
I want to execute a short python script that also print its source (so I can see which commands are executed).
The script is something like this:
command1()
#command2()
command3()
print some_variable_that_contain_src
The real application is that I want to run a script from IPython with the run -i magic and have as output the source (i.e. the commands executed). In this way I can check which commands are commented at every execution. Moreover, if executed in a Notebook I leave a trace of which commands have been used.
Solution
Using korylprince solution I end up with this one-liner to be put at the beginning of the script:
with open(__file__) as f: print '\n'.join(f.read().split('\n')[1:])
This will print the script source except the first line (that would be only noise). It's also easy to modify the slicing in order to print a different "slice" of the script.
If you want to print the whole file instead, the one-liner simplifies to:
with open(__file__) as f: print f.read()

As long as you're not doing anything crazy with packages, put this at the top of your script
with open(__file__) as f:
print f.read()
Which will read in the current file and print it out.
For python 3 make sure to use instead
print(f.read())

For the most simple answer:
import my_module
print open(my_module.__file__).read()
I also tried using the inspect package.
import inspect
import my_module
source_list = inspect.getsourcelines(my_module)
Will give you a list of strings with the source code defined in it
for line in source_list[0]:
print line
Will print out the entire source code in a readable manner

Related

How to export Python printed output to txt file at the end of code

I have several thousand lines of code that all ultimately results in a few strings being printed using print() calls. Is there a way to, at the bottom of my code, export everything that has been printed to a text file?
This will help.
python main.py > output.txt
The operator > redirects the output of main.py from stdout to the regular file output.txt.
You can do this with redirection in your shell or reopening sys.stdout. Here are both ways:
Reopen sys.stdout:
At the beginning of your code, you can use this code:
import sys
sys.stdout = open('logfile', 'w')
# ... rest of your program ...
and everything printed to standard output (including print() calls) will be written to logfile. This method will always work.
Redirection in your shell:
This is my preferred method if you're running the script from the command line every time. In some niche cases, this won't work (ie: the script is being run by some other program), but it will work for 90% of cases. You can simply run your original script like this:
python myFile.py > logfile
and everything will be written to logfile. If for some reason this doesn't work for you, use method #1.

Loop an existing script

I'm using a script from a third party I can't modify or show (let's call it original.py) which takes a file and produces some calculations. At the end it ouputs a result (using the print statment).
Since I have many files I decided to make a second script that gets all wanted files and runs them through the original.py
1st get list of all files to run
2nd run each file through the original.py
3rd obtain results from each file
I have the 1st and 2nd step. However, the end result only saves the calculations from the last file it read.
import sys
import original
import glob
import os
fn=str(sys.argv[1])
for filename in sys.argv[1:]:
print(filename)
ficheiros = [f for f in glob.glob(fn)]
for ficheiro in ficheiros:
original.file = bytes(ficheiro,'utf-8')
original.function()
To summarize:
Knowing I can't change the original script (which is made with a print statement) how can I obtain the results for each loop? Is there a better way than using a for loop?.
The first script can be invoked with python original.py
It requires the file to be changed manually inside the script in the original.file line.
This script outputs the result in the console and I redirect it with: python original.py > result.txt
At the moment when I try to run my script, it reads all the correct files in the folder but only returns the results for the last file.
#
(I tried to reformulate the question hopefully it's easier to understand)
#
The problem is due to a mistake in the ````ficheiros = [f for f in glob.glob(fn)]`````it's only reading one file, hence only outputting one result.
Thanks for the time.sleep() trick in the comments.
Solved:
I changed the initial part to:
fn=str(sys.argv[1])
ficheiros= []
for filename in sys.argv[1:]:
ficheiros.append(filename)
#print(filename)
and now it correctly reads all the files and it outputs all the results
Depending on your operating system there are different ways to take what is printed to the console and append it to a file.
For example on Linux, you could run this file that calls original.py for every file python yourfile.py >> outputfile.txt, which will then effectively save everything that is printed into outputfile.txt.
The syntax is similar for Windows.
I'm not quite sure what you're asking, but you could try one of these:
Either redirecting all output to a file for later use, by running the script like so: python secondscript.py > outfilename.txt
Or, and this might or might not work for you, redefining the print command to a function that outputs the result how you want, eg:
def print(x):
with open('outfile.txt','w') as f:
f.write('example: ' + x)
If you choose the second option, I recommend saving the old print function (oldprint = print) so you can restore and use the regular print later.
I don't know if I got exactly what you want. You have a first script named original.py which takes some arguments and returns things in the form of print statements and you would like to grab these prints statements in your scripts to do things?
If so, a solution could be the subprocess module:
Let's say that this is original.py:
print("Hi, I'm original.py")
print("print me!")
And this is main.py:
import subprocess
script_path = "original.py"
print("Executing ", script_path)
process = subprocess.Popen(["python3", script_path], stdout=subprocess.PIPE)
for line in process.stdout:
print(line.decode("utf8"))
You can easily add more arguments in the Popen call like ["arg1", "arg2",] etc.
Output:
Executing original.py
Hi, I'm original.py
print me!
and you can grab the lines in the main.py to do what you want with them.

python read data from variable and write to a file (no print) which i wanted to use later as backup data

I am new to python and programming. Starting to try few things for my project..
My problem is as below
p=subprocess.Popen(Some command which gives me output],stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
p.wait()
content=p.stdout.readlines()
for line in content:
filedata=line.lstrip().rstrip()
-----> I want this filedata output to open and save it to a file.
If i use print filedata it works and gives me exactly what i wanted but i donot want to print and wanted to use this data later.
Thanks in advance..
You can do that in following two ways.
Option one uses more traditional way of file handling, I have used with statement, using with statement you don't have to worry about closing the file
Option two, which makes use of pathlib module and this is new in version 3.4 (I recommend using this)
somefile.txt is the full file path in file system. I've also included documentation links and I highly recommend going through those.
OPTION ONE
p=subprocess.Popen(Some command which gives me output],stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
p.wait()
content=p.stdout.readlines()
for line in content:
filedata=line.lstrip().rstrip()
with open('somefile.txt', 'a') as file:
file.write(filedata + '\n')
Documentation for The with Statement
OPTION TWO - For Python 3.4 or above
import pathlib
p=subprocess.Popen(Some command which gives me output],stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
p.wait()
content=p.stdout.readlines()
for line in content:
filedata=line.lstrip().rstrip()
pathlib.Path('somefile.txt').write_text(filedata + '\n')
Documentation on Pathlib module

how to import files from command line in python

I am using python and I am supposed to read a file from command line for further processing. My input file has a binary that should be read for further processing. Here is my input file sub.py:
CODE = " \x55\x48\x8b\x05\xb8\x13\x00\x00"
and my main file which should read this is like the following:
import pyvex
import archinfo
import fileinput
import sys
filename = sys.argv[-1]
f = open(sys.argv[-1],"r")
CODE = f.read()
f.close()
print CODE
#CODE = b"\x55\x48\x8b\x05\xb8\x13\x00\x00"
# translate an AMD64 basic block (of nops) at 0x400400 into VEX
irsb = pyvex.IRSB(CODE, 0x1000, archinfo.ArchAMD64())
# pretty-print the basic block
irsb.pp()
# this is the IR Expression of the jump target of the unconditional exit at the end of the basic block
print irsb.next
# this is the type of the unconditional exit (i.e., a call, ret, syscall, etc)
print irsb.jumpkind
# you can also pretty-print it
irsb.next.pp()
# iterate through each statement and print all the statements
for stmt in irsb.statements:
stmt.pp()
# pretty-print the IR expression representing the data, and the *type* of that IR expression written by every store statement
import pyvex
for stmt in irsb.statements:
if isinstance(stmt, pyvex.IRStmt.Store):
print "Data:",
stmt.data.pp()
print ""
print "Type:",
print stmt.data.result_type
print ""
# pretty-print the condition and jump target of every conditional exit from the basic block
for stmt in irsb.statements:
if isinstance(stmt, pyvex.IRStmt.Exit):
print "Condition:",
stmt.guard.pp()
print ""
print "Target:",
stmt.dst.pp()
print ""
# these are the types of every temp in the IRSB
print irsb.tyenv.types
# here is one way to get the type of temp 0
print irsb.tyenv.types[0]
The problem is that when I run "python maincode.py sub.py' it reads the code as content of the file but its output is completely different from when I directly add CODE into the statement irsb = pyvex.IRSB(CODE, 0x1000, archinfo.ArchAMD64()). Does anyone know what is the problem and how can I solve it? I even use importing from inputfile but it does not read a text.
Have you considered the __import__ way?
You could do
mod = __import__(sys.argv[-1])
print mod.CODE
and just pass the filename without the .py extension as your command line argument:
python maincode.py sub
EDIT: Apparently using __import__ is discouraged. Instead though you can use importlib module:
import sys,importlib
mod = importlib.import_module(sys.argv[-1])
print mod.CODE
..and it should work the same as using __import__
If you need to pass a path to the module, one way is if in each of the directories you added an empty file named
__init__.py
That will allow python to interpret the directories as module namespaces, and you can then pass the path in its module form: python maincode.py path.to.subfolder.sub
If for some reason you cannot or don't want to add the directories as namespaces, and don't want to add the init.py files everywhere, you could also use imp.find_module. Your maincode.py would instead look like this:
import sys, imp
mod = imp.find_module("sub","/path/to/subfolder/")
print mod.code
You'll have to write code which breaks apart your command line input into the module part "sub" and the folder path "/path/to/subfolder/" though. Does that make sense? Once its ready you'll call it like you expect, python maincode.py /path/to/subfolder/sub/
you're reading the code as text, while when reading as file you're likely reading as binary
you probably need to convert binary to text of vice-versa to make this work
Binary to String/Text in Python

Print output to a file using another Python module

I have two python modules: buildContent.py which contains code that results in output i want. buildRun.py which i run in order to redirect the output to a file.
I'm trying to save the output from buildContent.py to a file and I did something like this in the buildRun.py:
import buildContent
import sys
with open('out.xhtml', 'w') as f:
sys.stdout = f
print buildContent
I can see my output in the console but the file result is:
<module 'buildContent' from 'here's my path to the file'>
what to do?
the redirection is working properly.
if you replace your print statement with a string you will see that it has
worked.
The reason for that output is that you are not calling any functions within buildcontent, merely importing it.
The solution is to run the buildContent file from within the above where your print statement should be.
see this question for an example
Instead of printing buildContent, just execute that module with the required parameters. Not sure of the content of buildContent but something like this should work:
buildContent(data)
This way the code inside buildContent will run on the "data" and print the results (if the print statements are given in the module). If you did not include print statements in buildContent, collect the output into a variable and print that variable. Something like this:
var = buildContent(data)
print var
If you do not need any data atall to run buildContent, just run:
buildContent()

Categories

Resources