2

I would like to write a function in Python that will take arguments just like print does but instead of printing the strings to stdout, I would like to write the strings formatted into a text file.

How do I define the arguments for such a function arguments to accept the string formatting, I'm wondering?

I am looking for something that would replace

print "Test"

with

MyLog "Test"

but the % rguments should also be supported. So far I have only come up with this:

def logger(txt):    
fh = open (LOGFILE, "a") #Get handle in append mode
fh.write(txt)
fh.close()
print txt
return True 

which works fine for a simple string but i don't think it'll take the % arguments nor will I be able to call it like logger "TEST"

stdcerr
  • 13,725
  • 25
  • 71
  • 128
  • the same file each time? – Pedro del Sol Nov 07 '12 at 17:35
  • Do you mean you want to write a function you can call like `my_function arg1 arg2` or do you just need a way to write to a file using a builtin function? – Vortexfive Nov 07 '12 at 17:41
  • Well, I can e.g. call print "Test" and I would like to be able to just replace print with MyLog "Test" e.g. – stdcerr Nov 07 '12 at 17:44
  • `print` is a statement in Python2.x, and you can't add another statement to the language. You can however, use specific syntax for `print` as a statement to make it write to a file (e.g. `print >> log_file_object, "Test"`. – Sam Mussmann Nov 07 '12 at 17:48
  • 1
    `"string with %s formats %d" % ('3', 3)"` will always evaluate to a string, even as an argument to a function. What have you tried? – Sam Mussmann Nov 07 '12 at 17:50

3 Answers3

5

You can use the "print chevron" statement to do what you want like this:

with open('filename.txt', 'w') as f:
  print >> f, my_object

See the documentation for the print statement.

Of course, it probably is better practice to use the print() function as Martijn Pieters suggests.

Update

If I change your logger function to use the print chevron syntax, I get this:

def logger(txt):    
  fh = open (LOGFILE, "a") #Get handle in append mode
  fh.write(txt)
  fh.close()
  print >>fh, txt
  return True 

If you call this function like:

now, duration = 4.0, 2.0
logger("User request at %f time took %f seconds." % (now, duration))

You'll have a line in your log file that looks like this:

User request at 4.0 time took 2.0 seconds.

So you can use this with the % formatting (although you really should take a look at the new-style formatting), but you won't be able to call it like:

logger "User request at %f time took %f seconds." % (now, duration)

That's because print is a simple statement, which is a language level construct, and you can't add those to Python.

Community
  • 1
  • 1
Sam Mussmann
  • 5,883
  • 2
  • 29
  • 43
4

print() already lets you do that:

print(somestring, file=someopenfile)

If you are on python 2, use from __future__ import print_function to get the same functionality.

You can always implement a function with the same arguments as the print function and use that as a replacement, or use wildcard arguments (*args, **kw), then add the file keyword argument as needed. You can always reach the original builtin print() function via the __builtins__ structure:

def print(*args, **kw):
    if 'file' not in kw:
        # print to a file instead of stdout
        kw['file'] = someopenfile
    return __builtins__.print(*args, **kw)
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
1

Since by default print outputs to sys.stdout, you could create a contextmanager as described in this answer of mine, which would allow you to use regular print, regardless of whether you're using the statement or a function version.

Community
  • 1
  • 1
martineau
  • 119,623
  • 25
  • 170
  • 301