Best way to print a module?

  • Thread starter Martin De Kauwe
  • Start date
M

Martin De Kauwe

Hi,

If I wanted to print an entire module, skipping the attributes
starting with "__" is there an *optimal* way? Currently I am doing
something like this. Note I am just using sys here to make the point

import sys

data = []
for attr in sys.__dict__.keys():
if not attr.startswith('__') and not attr.endswith('__'):
attr_val = getattr(sys, attr)
data.append((attr, attr_val))
data.sort()
for i in data:
print "%s = %s" % (i[0], i[1])

Clearly this would be quicker if I didn't store it and sort the
output, i.e.

for attr in sys.__dict__.keys():
if not attr.startswith('__') and not attr.endswith('__'):
attr_val = getattr(sys, attr)
print "%s = %s" % (attr, attr_val)

Anyway if there is a better way it would be useful to hear it...

Many thanks,

Martin
 
R

rantingrick

Hi,

If I wanted to print an entire module, skipping the attributes
starting with "__" is there an *optimal* way? Currently I am doing
something like this. Note I am just using sys here to make the point

import sys

data = []
for attr in sys.__dict__.keys():
    if not attr.startswith('__') and not attr.endswith('__'):
        attr_val = getattr(sys, attr)
        data.append((attr, attr_val))
data.sort()
for i in data:
    print "%s = %s" % (i[0], i[1])

Clearly this would be quicker if I didn't store it and sort the
output, i.e.

for attr in sys.__dict__.keys():
    if not attr.startswith('__') and not attr.endswith('__'):
        attr_val = getattr(sys, attr)
        print "%s = %s" % (attr, attr_val)

Anyway if there is a better way it would be useful to hear it...

Many thanks,

Martin

Martin, have you considered that your custom function is just re-
inventing the built-in dir() function? I would suggest using a list
comprehension against the dir() function with a predicate to remove
anything that startswith '_'. Here's some Ruby code to solve the
problem. I'll let you figure out the Python equivalent.

rb> ['_hello', '__goodbye__', 'whatsup'].select{|x| x[0].chr != '_'}
["whatsup"]
 
M

Martin De Kauwe

Hi,

Tim yes I had a feeling my posting might be read as ambiguous! Sorry I
was trying to quickly think of a good example. Essentially I have a
set of .ini parameter files which I read into my program using
configobj, I then replace the default module parameters if the user
file is different (in my program). When it comes to writing the data
back out I need to potentially loop over 5 module files and I need to
ignore the superfluous information. My guess is that the way I am
doing it might be a little on the slow side, hence the posting. Like
you said it might be that the way I am doing it is "fine", I just
wanted to see if there was a better way that is all.

Rantingrick I did actually try the dir() to start with, I can't
remember why I changed back. I will try your suggestion and see
(thanks)

So instead of sys as per my example my module more realistically looks
like this:

params.py

apples = 12.0
cats = 14.0
dogs = 1.3

so my fuller example then

import sys
sys.path.append("/Users/mdekauwe/Desktop/")
import params

#params.py contains
#apples = 12.0
#cats = 14.0
#dogs = 1.3

fname = "test.asc"
try:
ofile = open(fname, 'w')
except IOError:
raise IOError("Can't open %s file for write" % fname)

data = []
for attr in params.__dict__.keys():
if not attr.startswith('__') and not attr.endswith('__'):
attr_val = getattr(params, attr)
data.append((attr, attr_val))

data.sort()
try:
ofile.write("[params]\n")
for i in data:
ofile.write("%s = %s\n" % (i[0], i[1]))
except IOError:
raise IOError("Error writing params files, params section")


etc, etc
thanks
 
M

Martin De Kauwe

Trying to follow the suggestion this would be the alternate
implementation.

import sys
sys.path.append("/Users/mdekauwe/Desktop/")
import params

#params.py contains
#apples = 12.0
#cats = 14.0
#dogs = 1.3

fname = "test.asc"
try:
ofile = open(fname, 'w')
except IOError:
raise IOError("Can't open %s file for write" % fname)

attributes = [attr for attr in dir(params) if not
attr.startswith('__')]
attributes.sort()

try:
ofile.write("[params]\n")
for i in attributes:
ofile.write("%s = %s\n" % (i, getattr(params, i)))
except IOError:
raise IOError("Error writing params files, params section")

Is that a better version? I honestly don't know.

thanks
 
S

Steven D'Aprano

Tim said:
Your question is somewhat ambiguous. When I read "print an entire
module", I assumed you were asking for a way to print the source code,
perhaps with syntax coloring.

Surely there is no reason to have an "optimal" method of doing this --
this is never going to be in an inner loop.

Regardless of an inner loop or not, the time required for IO (reading the
file from disk, writing it to a printer) will be much larger than the time
required to skip dunder (double-underscore) objects.
If you have a method that works,
there is little justification to optimize...

Pretty much.

HOWEVER, having agreed with you in general, in this specific case it is
obvious to me from context that the OP doesn't want to print the source
code of the module, but the module's names and their values.

I'd try a couple of approaches:

- use dir() or vars() to get the module's names, then loop and print each
one;

- make a shallow copy of the module __dict__, less dunder names, and pass it
to the prettyprint module for printing.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,154
Members
46,702
Latest member
LukasConde

Latest Threads

Top