Adding Timestamp to Print Function - python

I am currently writing myself a program in python 3.7 and was wanting to add a timestamp to the front of my printing in the format:
<hh:mm:ss> WhateverImPrinting
I took a look at other forums and I get some code which used sys.stdout, overwriting the text using the write function.
My issue is it is returning the timestamp both before and after my print.
e.g. <14:21:51> Hello<14:21:51>
This should be:
<14:21:51> Hello
My code:
old_f = sys.stdout # Get old print output
class PrintTimestamp:
# #staticmethod
def write(self, x):
old_f.write("<{}> {}".format(str(pC.Timestamp.hhmmss()), x))
# #staticmethod
def flush(self):
pass
sys.stdout = PrintTimestamp() # Set new print output
I have run this after all my classes and functions, but before if __name__ == '__main__'

You can simply override print function in Python 3.x:
from datetime import datetime
old_print = print
def timestamped_print(*args, **kwargs):
old_print(datetime.now(), *args, **kwargs)
print = timestamped_print
then
print("Test")
should print
2019-09-30 01:23:44.67890 Test

Here you go.
from datetime import datetime
class PrintTimeStamp():
def write(self,x):
ts = str(datetime.now.hour())+":"+str(datetime.now().minute)+":"+str(datetime.now().second)
print("<{}> {}".format(str(ts),x)
pts = PrintTimeStamp()
pts.write("test")

Related

Python error in loading JSON when ending function with return

I'm having an issue returning my function when trying to load a JSON file. Here is the code to look at.
#!/usr/bin/python
import os
import json
class Math(object):
def __init__(self):
self.__mathjsonfile__ = os.path.join(os.getcwd(),os.path.dirname(__file__),'server','json_data','math.json')
def load_mathfile(self):
with open(self.__mathjsonfile__) as i:
data = i.read()
math_data = json.loads(data)
self.math_data = math_data
def read_mathdata(self):
for numbers in self.math_data['numbers']:
print numbers['zero']
for symbols in self.math_data['symbols']:
print symbols['percent']
start = Math()
start.read_mathdata()
I've ended the last function with () because I can't seem to end read_mathdata with return and still print the JSON information.
You can return data from a function using the straightforward way, like that below:
class Math(object):
def __init__(self):
self.__mathjsonfile__ = os.path.join(os.getcwd(),os.path.dirname(__file__),'server','json_data','math.json')
def load_mathfile(self):
with open(self.__mathjsonfile__) as i:
data = i.read()
math_data = json.loads(data)
self.math_data = math_data
def read_mathdata(self):
data = []
for numbers in self.math_data['numbers']:
data.append(numbers['zero'])
for symbols in self.math_data['symbols']:
data.append(numbers['percent'])
return data
start = Math()
my_data = start.read_mathdata()
print my_data
If you want to make read_mathdata a property you can by using the property decorator:
#property
def read_mathdata(self):
pass
Then you can call it like so:
my_data = start.read_mathdata
Why you'd want to do any of this is beyond me.

Get function object of caller in Python 2.7?

In playing with inspect and reading the other questions here, I still cannot figure out how to get the function object of the caller more cleanly than to load the module by its path and then find the function within that.
In other words, how would you complete the following so that caller() returns a method object?
import inspect
def caller():
frame = inspect.stack()[2]
code = frame[0]
path = frame[1]
line = frame[2]
name = frame[3] # function NAME string
# TODO: now what?
return func
def cry_wolf():
func = caller()
print "%s cried 'WOLF!'" % (func.__name__,)
def peter():
cry_wolf()
Remember, I already know the function name but what I'm trying to access is the function object that the calling code is running in. The result desired is:
peter cried 'WOLF!'
DONE! Thanks to user 61612, I have completed this code:
import imp, inspect, sys
def caller():
frame = inspect.stack()[2]
code = frame[0]
path = frame[1]
line = frame[2]
name = frame[3]
return code.f_globals[name]
def cry_wolf():
func = caller()
print "%s cried 'WOLF!'" % (func.__name__,)
def peter():
cry_wolf()
Awesome!
Frame objects have the f_globals attribute:
import inspect
def caller():
tup = inspect.stack()[2]
return tup[0].f_globals[tup[3]] # <function peter at address>
def cry_wolf():
func = caller()
print("%s cried 'WOLF!'" % (func.__name__,)) # peter cried 'WOLF!'
def peter():
cry_wolf()

python: generating methods for a convenience class programatically

So I've written a module that contains a bunch of functions to easily interact with a subprocess. This subprocess has a whole bunch of settings that let you change how it formats and behaves. I realized that it'd be nice to have a convenience class that you could use as a handler to store the settings you prefer to use and pass them on to the module level functions. here's the example code I'm doing testing with:
import inspect
class MyHandler(object):
def __init__(self):
self.format_string='class format string'
self.database='class database'
self.mode = "class mode"
def rename(self, *args, **kwargs):
self._pass_to_function(rename, *args, **kwargs)
def _pass_to_function(self, function, *overrided_args, **overrided_kwargs):
# get the function's remaining arguments with the inspect module
functon_kwargs = inspect.getargspec(function)[0][len(overrided_args):]
handler_vars = vars(self)
kwargs_to_pass = {}
for arg in functon_kwargs:
if arg in handler_vars:
kwargs_to_pass[arg] = handler_vars[arg]
for arg in overrided_kwargs:
kwargs_to_pass[arg] = overrided_kwargs[arg]
return function(*overrided_args, **kwargs_to_pass)
def rename(targets, format_string=None, database=None, mode=None,
not_in_class='None'):
print 'targets = {}'.format(targets)
print 'format_string = {}'.format(format_string)
print 'database = {}'.format(database)
print 'mode = {}'.format(mode)
print 'not_in_class = {}\n'.format(not_in_class)
return
The thing I like about this solution is that it uses the attributes stored in the class, but you can easily override them by simply adding them to the method call if you want a one-off with a different setting. To do this I have the _pass_to_function as a kind of wrapper function to parse and fill in the needed settings and overrides. Here's how it looks:
>>> import argstest
>>> argstest.rename('some_file.avi', database='some database')
targets = some_file.avi
format_string = None
database = some database
mode = None
not_in_class = None
>>> tst = argstest.MyHandler()
>>> tst.rename('some_file.avi')
targets = some_file.avi
format_string = class format string
database = class database
mode = class mode
not_in_class = None
>>> tst.rename('some_file.avi', 'one off format string', not_in_class=True)
targets = some_file.avi
format_string = one off format string
database = class database
mode = class mode
not_in_class = True
Now in my real module I have dozens of module-level functions that I want to access from the handler class. Ideally they would generate automatically based on the functions in the module. Seeing as how all the methods are only going to be passing everything to _pass_to_function I get the sense that this shouldn't be very difficult but I'm having a lot of trouble figuring out exactly how.
I've read about using type to generate a meta-class, but I don't see how I would use it in this situation. Am I not seeing how I could use type? Should I use some sort of module level script that adds the functions with setattr? Is what I was doing the better/clearer way to do things?
Any and all advice would be appreciated.
Okay, I think I've answered my own question for now. This is how the module looks:
import inspect
import sys
from types import MethodType
class MyHandler(object):
def __init__(self):
self.format_string = 'class format string'
self.database = 'class database'
self.mode = "class mode"
self._populate_methods()
def _populate_methods(self):
to_add = inspect.getmembers(sys.modules[__name__], inspect.isfunction)
to_add = [x[0] for x in to_add if not x[0].startswith('_')]
for func_name in to_add:
func = getattr(sys.modules[__name__], func_name) # strings to functions
self._add_function_as_method(func_name, func)
def _add_function_as_method(self, func_name, func):
def f(self, *args, **kwargs): # the template for the method we'll add
return self._pass_to_function(func, *args, **kwargs)
setattr(MyHandler, func_name, MethodType(f, None, MyHandler))
def _pass_to_function(self, function, *overrided_args, **overrided_kwargs):
functon_kwargs = inspect.getargspec(function)[0][len(overrided_args):]
handler_vars = vars(self)
kwargs_to_pass = {}
for arg in functon_kwargs:
if arg in handler_vars:
kwargs_to_pass[arg] = handler_vars[arg]
for arg in overrided_kwargs:
kwargs_to_pass[arg] = overrided_kwargs[arg]
return function(*overrided_args, **kwargs_to_pass)
def rename(targets, format_string=None, database=None, mode=None,
not_in_class='None'):
print 'targets = {}'.format(targets)
print 'format_string = {}'.format(format_string)
print 'database = {}'.format(database)
print 'mode = {}'.format(mode)
print 'not_in_class = {}\n'.format(not_in_class)
return
def something_else():
print "this function should become a method"
def _not_a_member():
print "this function should not become a method"
I've added the _populate_methods and the _add_function_as_method member functions. the _populate_methods function gets the name of all "public" functions in the module, de-references them to their function and passes each one though _add_function_as_method. All this method does is use an internal function to capture arguments and sent them to _pass_to_function, and set that function as a method using setattr.
phew
so it works, but I'm still wondering if there isn't a clearer or more straight forward way to get this done. I'd be very grateful if anyone could chime in.

saving the data after it was printed to screen python

Is there a way to save data after it was printed to the screen?
for example:
lets have some arbitrary function
def main():
if something:
for i in range(n):
output= "%f %f" %(n,d)
print output
if something:
for i in range(n):
output="%f %f" %(n,d)
print output
fileout=open("data.csv", "a")
fileout.write(output)
this will only write the last data for the last range in for loop.
Edit: I want to ask a user if she/he wants to save that data
Declare your output variable(s) at the highest level of scope in your program first. This will allow it to be written to a file in the manner you've programmed.
If you want to prompt a user for a location to save the file(s), that's merely this:
out1 = raw_input("Where would you like to save this? ")
You can do the same for another output file variable.
just use this in the if conditions:
print >>fileout, output #this will save the output to the data.csv file
Change your code...
1: If you really want to use print, change sys.stdout to a different stream
2: use files
1
import sys
oldstdout=sys.stdout
f=open("myfile","w")
sys.stdout=f
def main():
if something:
for i in range(n):
print "%f %f"%(n,d)
if something:
for i in range(n):
print "%f %f"%(n,d)
2
f=open("myfile","w")
def main():
if something:
for i in range(n):
f.write("%f %f"%(n,d))
if something:
for i in range(n):
f.write("%f %f"%(n,d))
Here is a (somewhat pathological) example that will let you both print and save the statements that you print in a global list (which we'll call OUTPUT):
import sys
OUTPUT = []
def print_wrapper(method):
class result(object):
def __init__(self, file_obj):
self.file_obj = file_obj
def __getattr__(self, name):
return getattr(self.file_obj, name)
def write(self, value):
OUTPUT.append(value)
return self.file_obj.write(value)
return result(method)
original_stdout = sys.stdout
sys.stdout = print_wrapper(original_stdout)
# This will still print, but will add 'Hi' and '\n' to OUTPUT as well
print 'Hi'
# This will still print, but will add 'None' and '\n' to OUTPUT as well
print None
# This uses the original stdout to print, so won't change OUTPUT
original_stdout.write(repr(OUTPUT))
original_stdout.write('\n')
or you could alternately prepare yourself for Python 3 (or just use it) and wrap the print method itself:
from __future__ import print_function # must have Python >= 2.6
OUTPUT = []
def wrap_print(method):
def result(value):
OUTPUT.append(value)
return method(value)
return result
old_print = print
print = wrap_print(old_print)
print('Hi')
print(None)
old_print(OUTPUT)

How to make a class that acts like a string?

I have a context manager that captures output to a string for a block of code indented under a with statement. This context manager yields a custom result object which will, when the block has finished executing, contain the captured output.
from contextlib import contextmanager
#contextmanager
def capturing():
"Captures output within a 'with' block."
from cStringIO import StringIO
class result(object):
def __init__(self):
self._result = None
def __str__(self):
return self._result
try:
stringio = StringIO()
out, err, sys.stdout, sys.stderr = sys.stdout, sys.stderr, stringio, stringio
output = result()
yield output
finally:
output._result, sys.stdout, sys.stderr = stringio.getvalue(), out, err
stringio.close()
with capturing() as text:
print "foo bar baz",
print str(text) # prints "foo bar baz"
I can't just return a string, of course, because strings are immutable and thus the one the user gets back from the with statement can't be changed after their block of code runs. However, it is something of a drag to have to explicitly convert the result object to a string after the fact with str (I also played with making the object callable as a bit of syntactic sugar).
So is it possible to make the result instance act like a string, in that it does in fact return a string when named? I tried implementing __get__, but that appears to only work on attributes. Or is what I want to do not really possible?
How to make a class that acts like a string?
Subclass str
import os
class LikeAStr(str):
'''Making a class like a str object; or more precisely
making a str subclass with added contextmanager functionality.'''
def __init__(self, diff_directory):
self._iwd = os.getcwd()
self._cwd = diff_directory
def __enter__(self):
return self
def __exit__(self, ext_typ, exc_value, traceback):
try: os.chdir(self._iwd) # might get deleted within the "with" statement
except: pass
def __str__(self):
return self._cwd
def __repr__(self):
return repr(self._cwd)
astr = LikeAStr('C:\\')
with LikeAStr('C:\\') as astr:
print 1, os.getcwd()
os.chdir( astr ) # expects str() or unicode() not some other class
print 2, os.getcwd()
#
# out of with block
print 3, os.getcwd()
print 4, astr == 'C:\\'
Output:
1 D:\Projects\Python\
2 C:\
3 D:\Projects\Python\
4 True
I don't believe there is a clean way to do what you want.
text is defined in the modules' globals() dict.
You would have to modify this globals() dict from within the capturing object:
The code below would break if you tried to use the with from within a function, since then text would be in the function's scope, not the globals.
import sys
import cStringIO
class capturing(object):
def __init__(self,varname):
self.varname=varname
def __enter__(self):
self.stringio=cStringIO.StringIO()
self.out, sys.stdout = sys.stdout, self.stringio
self.err, sys.stderr = sys.stderr, self.stringio
return self
def __exit__(self,ext_type,exc_value,traceback):
sys.stdout = self.out
sys.stderr = self.err
self._result = self.stringio.getvalue()
globals()[self.varname]=self._result
def __str__(self):
return self._result
with capturing('text') as text:
print("foo bar baz")
print(text) # prints "foo bar baz"
# foo bar baz
print(repr(text))
# 'foo bar baz\n'
At first glance, it looked like UserString (well, actually MutableString, but that's going away in Python 3.0) was basically what I wanted. Unfortunately, UserString doesn't work quite enough like a string; I was getting some odd formatting in print statements ending in commas that worked fine with str strings. (It appears you get an extra space printed if it's not a "real" string, or something.) I had the same issue with a toy class I created to play with wrapping a string. I didn't take the time to track down the cause, but it appears UserString is most useful as an example.
I actually ended up using a bytearray because it works enough like a string for most purposes, but is mutable. I also wrote a separate version that splitlines() the text into a list. This works great and is actually better for my immediate use case, which is removing "extra" blank lines in the concatenated output of various functions. Here's that version:
import sys
from contextlib import contextmanager
#contextmanager
def capturinglines(output=None):
"Captures lines of output to a list."
from cStringIO import StringIO
try:
output = [] if output is None else output
stringio = StringIO()
out, err = sys.stdout, sys.stderr
sys.stdout, sys.stderr = stringio, stringio
yield output
finally:
sys.stdout, sys.stderr = out, err
output.extend(stringio.getvalue().splitlines())
stringio.close()
Usage:
with capturinglines() as output:
print "foo"
print "bar"
print output
['foo', 'bar']
with capturinglines(output): # append to existing list
print "baz"
print output
['foo', 'bar', 'baz']
I think you might be able to build something like this.
import StringIO
capturing = StringIO.StringIO()
print( "foo bar baz", file= capturing )
Now 'foo bar baz\n' == capturing.getvalue()
That's the easiest. It works perfectly with no extra work, except to fix your print functions to use the file= argument.
How to make a class that acts like a string?
If you don't want to subclass str for whatever reason:
class StrBuiltin(object):
def __init__(self, astr=''):
self._str = astr
def __enter__(self):
return self
def __exit__(self, ext_typ, exc_value, traceback):
pass # do stuff
def __str__(self):
return self._str
def __repr__(self):
return repr(self._str)
def __eq__(self, lvalue):
return lvalue == self._str
def str(self):
'''pretend to "convert to a str"'''
return self._str
astr = StrBuiltin('Eggs&spam')
if isinstance( astr.str(), str):
print 'Is like a str.'
else:
print 'Is not like a str.'
I know you didn't want to do str(MyClass) but MyClass.str() kind of implies, to me, that this class is expected to expose itself as a str to functions which expect a str as part of the object. Instead of some unexpected result of "who know's what would be returned by str( SomeObject ).
This is an old question but is an interesting one.
Using the idea from #S.Lott you can use contextmanagers to create a more robust and reusable tool:
#contextmanager
def redefine_print(stream):
global print
from functools import partial, wraps
old_print = print
try:
print = wraps(print)(partial(print, file=stream))
yield print
finally:
print = old_print
sample use with file-like objects:
with open('file', 'a+') as stream:
print('a') # print in the interface
with redefine_print(stream):
print('b') # print in the file
print('c') # print in the interface
stream.seek(0)
print(stream.readlines())
sample use with StringIO objects
import io
stream = io.StringIO()
with redefine_print(stream) as xprint:
print('b') # add to the ioStream
xprint('x') # same as print, just to see how the object works
print(stream.getvalue()) # print the intercepted value
print(xprint.__doc__) # see how #wraps helps to keep print() signature

Categories