Re: Open a List of Files

2008-01-09 Thread Tim Chase
> You don't need "for fn in open_files.keys():", you can just use "for fn in
> open_files:", but simpler than that is to just use the dictionary values:
> 
> for fn in open_files.values():
> fn.close()

This can also work for standard variable names:

   for f in (messages, deliveries, actions, parts,
   recipients, viruses, esp_scores):
 f.close()

-tkc


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Open a List of Files

2008-01-09 Thread Terry Jones
> "BJ" == BJ Swope <[EMAIL PROTECTED]> writes:

I (at least) think the code looks much nicer.

BJ> #Referring to files to write in various places...
BJ> open_files['deliveries'].write(flat_line)
BJ> open_files['deliveries'].write('\n')

If you were doing a lot with the deliveries file at some point, you could
put the file descriptor into a local variable

  deliveries = open_files['deliveries']
  deliveries.write(flat_line)
  deliveries.write('\n')

BJ> #And finally to close the opened files
BJ> for fn in open_files.keys():
BJ> open_files[fn].close()

You don't need "for fn in open_files.keys():", you can just use "for fn in
open_files:", but simpler than that is to just use the dictionary values:

for fn in open_files.values():
fn.close()

Regards,
Terry
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Open a List of Files

2008-01-09 Thread Terry Jones
> "Fredrik" == Fredrik Lundh <[EMAIL PROTECTED]> writes:

Fredrik> Seriously, for a limited number of files, the dictionary approach
Fredrik> is mostly pointless; you end up replacing

Fredrik> foo = open("foo")
Fredrik> foo.write(...)

Fredrik> with

Fredrik> somedict["foo"] = open("foo")
Fredrik> somedict["foo"].write(...)

Yes, in some cases. But where you want to do multiple things you can always
pull the file descriptor of of the dict into a local var.

>> - It has less risk of error (much less repetition).

Fredrik> No, it hasn't.  There's more to type when using the files, and you
Fredrik> have *two* things you can misspell; that is, you're replacing a
Fredrik> NameError with either a NameError or a Key Error.

Well I meant less error risk in the context of opening the files. And I'm
happy to get a NameError or KeyError if I make the mistake you describe.
But bad code like this:

messages = open(os.path.join(host_path,'messages.txt'), 'wb')
deliveries = open(os.path.join(host_path,'deliveries.txt'), 'wb')
actions = open(os.path.join(host_path,'deliveries.txt'), 'wb')

doesn't give an error at all, and with all that identical and
semi-identical code it's much less obvious where the error is.

Cut & paste errors like this are pretty common, and they can be quite hard
to find (when they don't result in exceptions), in my experience.

>> - It allows your code to later take a string file tag and
>> write to that file by looking up its file descriptor in the dict.

Fredrik> Instead of allowing your code to take a file object and write to that 
Fredrik> file by writing to that file object?

No, see below:

>> - You can close all open files with a trivial loop.

Fredrik> Ok, this is actually an advantage.  Not that you need to do that very 
Fredrik> often, since Python does it for you.

Yes.  That's partly why I said it would make him a better programmer in
general, not just in Python.

Fredrik> And if you find yourself needing to do this a lot, you can of
Fredrik> course stuff all the output files in a list but *still* use the
Fredrik> variables to refer to the file when writing to them.

Yes, as above.

Fredrik> There is one case where a dictionary of files makes perfect sense, of 
Fredrik> course, and that's when you can associate the file with some *other* 
Fredrik> value that you're *already* using. (Say, a user name or a machine name 
Fredrik> or a severity level or something like that.)

Yes. That's what I meant by my original - badly worded - remark (see above)
that you could take a "string file tag" and use it to look up its file
descriptor.

Terry
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Open a List of Files

2008-01-09 Thread Fredrik Lundh
Paul Hankin wrote:

> Thanks Fredrik! I learnt something today.
> 
> I wonder if there's a reason why it doesn't raise an exception when
> you try to write to it? That would seem better to me than having it
> sometimes update variables and sometimes not.

probably because it returns a standard dictionary object, and Python's 
dictionary objects are writable.

(and if someone wants to reopen the old discussion about how Python 
absolutely definitely needs frozen dictionaries to be useful at all, 
please do so in a new thread ;-)



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Open a List of Files

2008-01-09 Thread Paul Hankin
On Jan 9, 10:02 am, Fredrik Lundh <[EMAIL PROTECTED]> wrote:
> Paul Hankin wrote:
> > This can be more cleanly written using locals()
>
> > for fn in filenames:
> > locals()[fn] = open(os.path.join(host_path, fname + '.txt', 'wb')
>
> from the reference manual:
>
>  locals()
>
>  Update and return a dictionary representing the current
>  local symbol table.
>
>  Warning: The contents of this dictionary should not be
>  modified; changes may not affect the values of local
>  variables used by the interpreter.

Thanks Fredrik! I learnt something today.

I wonder if there's a reason why it doesn't raise an exception when
you try to write to it? That would seem better to me than having it
sometimes update variables and sometimes not.

--
Paul Hankin
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Open a List of Files

2008-01-09 Thread Fredrik Lundh
Paul Hankin wrote:

> This can be more cleanly written using locals()
> 
> for fn in filenames:
> locals()[fn] = open(os.path.join(host_path, fname + '.txt', 'wb')

from the reference manual:

 locals()

 Update and return a dictionary representing the current
 local symbol table.

 Warning: The contents of this dictionary should not be
 modified; changes may not affect the values of local
 variables used by the interpreter.

examples:

 >>> def foo():
... locals()["foo"] = 1
... print foo
...
 >>> foo()


 >>> def foo():
... foo = 1
... locals()["foo"] = 2
... print foo
...
 >>> foo()
1



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Open a List of Files

2008-01-09 Thread Paul Hankin
On Jan 9, 2:41 am, Tim Chase <[EMAIL PROTECTED]> wrote:
> > I decided that I was just trying to be "too smooth by 1/2" so I fell back to
>
> > messages = open(os.path.join(host_path,'messages.txt'), 'wb')
> > deliveries = open(os.path.join(host_path,'deliveries.txt'), 'wb')
> > actions = open(os.path.join(host_path,'actions.txt'), 'wb')
> > parts = open(os.path.join(host_path,'parts.txt'), 'wb')
> > recipients = open(os.path.join(host_path,'recipients.txt'), 'wb')
> > viruses = open(os.path.join(host_path,'viruses.txt'), 'wb')
> > esp_scores = open(os.path.join(host_path,'esp_scores.txt'), 'wb')
>
> Another way to write this which reduces some of the code would be
>
>   filenames = ['messages', 'deliveries', 'actions', 'parts',
>     'recipients', 'viruses', 'esp_scores']
>
>   (messages, deliveries, actions, parts,
>     recipients, viruses, esp_scores) = [
>     open(os.path.join(host_path, '%s.txt' % fn), 'wb')
>     for fn in filenames
>     ]
>
> It becomes even more clear if you make an intermediate "opener"
> function such as
>
>   binwriter = lambda fname: open(
>       os.path.join(host_path, '%s.txt' % fname), 'wb')
>
>   (messages, deliveries, actions, parts,
>     recipients, viruses, esp_scores) = [
>     binwriter(fn) for fn in filenames]

This can be more cleanly written using locals()

for fn in filenames:
locals()[fn] = open(os.path.join(host_path, fname + '.txt', 'wb')

--
Paul Hankin
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Open a List of Files

2008-01-08 Thread Fredrik Lundh
Terry Jones wrote:

> I think you should revisit this decision.  Something like Fredrik's code is
> the way to go.

He used my suggestion, just for a few more files than he had in his 
original post.

Seriously, for a limited number of files, the dictionary approach is 
mostly pointless; you end up replacing

 foo = open("foo")
 foo.write(...)

with

 somedict["foo"] = open("foo")
 somedict["foo"].write(...)

which, frankly, sucks in a whole lot of ways.

>  It has multiple advantages:
> 
>  - It's much shorter.

For a small number of files, it isn't, really.

>  - It's arguably easier to add/remove to/from.

Only if you're not using the files you're opening; as soon you try to do 
something with them, it's more work.

>  - It has less risk of error (much less repetition).

No, it hasn't.  There's more to type when using the files, and you have 
*two* things you can misspell; that is, you're replacing a NameError 
with either a NameError or a KeyError.

>  - It allows your code to later take a string file tag and
>write to that file by looking up its file descriptor in the dict.

Instead of allowing your code to take a file object and write to that 
file by writing to that file object?

>  - You can close all open files with a trivial loop.

Ok, this is actually an advantage.  Not that you need to do that very 
often, since Python does it for you.  And if you find yourself needing 
to do this a lot, you can of course stuff all the output files in a list 
but *still* use the variables to refer to the file when writing to them.

:::

There is one case where a dictionary of files makes perfect sense, of 
course, and that's when you can associate the file with some *other* 
value that you're *already* using. (Say, a user name or a machine name 
or a severity level or something like that.)  But inventing your own 
string tags to use instead of variables is just plain bad design.



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Open a List of Files

2008-01-08 Thread BJ Swope
On Jan 8, 2008 9:34 PM, Terry Jones <[EMAIL PROTECTED]> wrote:

>
> I think you should revisit this decision.  Something like Fredrik's code
> is
> the way to go.  It has multiple advantages:
>
>  - It's much shorter.
>  - It's arguably easier to add/remove to/from.
>  - It has less risk of error (much less repetition).
>  - It allows your code to later take a string file tag and
>   write to that file by looking up its file descriptor in the dict.
>  - You can close all open files with a trivial loop.
>
> Also, if you start writing code like Fredrik's instead of like what you
> fell back on you'll make yourself a better programmer (in general, not
> just
> in Python).
>
> Terry
>


Thanks for the advice Terry.  With your prompting I went back and looked at
the examples and sought to understand them.

The results are...

#File Creations/Openings
def getfilename(host_path, fn):
return os.path.join(host_path, '%s.txt' % fn)

outfiles_list = ['messages', 'deliveries', 'actions', 'parts', 'recipients',
'viruses', 'esp_scores']
open_files = {}
for fn in outfiles_list:
open_files[fn] = open(getfilename(host_path, fn), 'wb')


#Referring to files to write in various places...
open_files['deliveries'].write(flat_line)
open_files['deliveries'].write('\n')


#And finally to close the opened files
for fn in open_files.keys():
open_files[fn].close()


I sure am glad I posted this to the list.  It is exactly the kind of stuff I
was hoping to find.

Again, to all who answered, Thank You!


BJ
-- 
http://mail.python.org/mailman/listinfo/python-list

Re: Open a List of Files

2008-01-08 Thread Tim Chase
> I decided that I was just trying to be "too smooth by 1/2" so I fell back to
> 
> messages = open(os.path.join(host_path,'messages.txt'), 'wb')
> deliveries = open(os.path.join(host_path,'deliveries.txt'), 'wb')
> actions = open(os.path.join(host_path,'actions.txt'), 'wb')
> parts = open(os.path.join(host_path,'parts.txt'), 'wb')
> recipients = open(os.path.join(host_path,'recipients.txt'), 'wb')
> viruses = open(os.path.join(host_path,'viruses.txt'), 'wb')
> esp_scores = open(os.path.join(host_path,'esp_scores.txt'), 'wb')


Another way to write this which reduces some of the code would be

  filenames = ['messages', 'deliveries', 'actions', 'parts',
'recipients', 'viruses', 'esp_scores']

  (messages, deliveries, actions, parts,
recipients, viruses, esp_scores) = [
open(os.path.join(host_path, '%s.txt' % fn), 'wb')
for fn in filenames
]


It becomes even more clear if you make an intermediate "opener"
function such as

  binwriter = lambda fname: open(
  os.path.join(host_path, '%s.txt' % fname), 'wb')

  (messages, deliveries, actions, parts,
recipients, viruses, esp_scores) = [
binwriter(fn) for fn in filenames]

This makes it easier to change intended functionality in one
place, rather than updating each line.  Additionally, it's easy
to add a new entry (just add the filename in the filename list,
and the variable-name in the assignment tuple).  It also makes it
clear that each one is getting the same treatment (that there's
not some outlier making you study matters carefully to figure out
that there isn't).

-tkc



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Open a List of Files

2008-01-08 Thread Terry Jones
Hi BJ

> > Fredrik Lundh <[EMAIL PROTECTED]> writes:
> > Or in a dict:
> >
> > open_files = {}
> > for fn in ['messages', 'recipients', 'viruses']:
> >open_files[fn] = open(getfilename(fn), 'w')
> 
> I decided that I was just trying to be "too smooth by 1/2" so I fell back
> to ...
> 
> messages = open(os.path.join(host_path,'messages.txt'), 'wb')
> deliveries = open(os.path.join(host_path,'deliveries.txt'), 'wb')
> actions = open(os.path.join(host_path,'actions.txt'), 'wb')
> parts = open(os.path.join(host_path,'parts.txt'), 'wb')
> recipients = open(os.path.join(host_path,'recipients.txt'), 'wb')
> viruses = open(os.path.join(host_path,'viruses.txt'), 'wb')
> esp_scores = open(os.path.join(host_path,'esp_scores.txt'), 'wb')

I think you should revisit this decision.  Something like Fredrik's code is
the way to go.  It has multiple advantages:

 - It's much shorter.
 - It's arguably easier to add/remove to/from.
 - It has less risk of error (much less repetition).
 - It allows your code to later take a string file tag and
   write to that file by looking up its file descriptor in the dict.
 - You can close all open files with a trivial loop.

Also, if you start writing code like Fredrik's instead of like what you
fell back on you'll make yourself a better programmer (in general, not just
in Python).

Terry
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Open a List of Files

2008-01-08 Thread BJ Swope
On Jan 8, 2008 7:22 AM, Hrvoje Niksic <[EMAIL PROTECTED]> wrote:

> Fredrik Lundh <[EMAIL PROTECTED]> writes:
>
> > BJ Swope wrote:
> >
> >> the code looks ok.  please define "not working".
> >>
> >> Yep, defining "not working" is always helpful! :)
> >>
> >> I want to have all 3 files open at the same time.  I will write to
> >> each of the files later in my script but just the last file is open
> >> for writing.
> >
> > to keep more than one file open, you need more than one variable, or a
> > variable that can hold more than one object.
> >
> > if the number of files may vary, put the file objects in a list.
>
> Or in a dict:
>
> open_files = {}
> for fn in ['messages', 'recipients', 'viruses']:
>open_files[fn] = open(getfilename(fn), 'w')
>
> # open_files['messages'] is the open file 'messages' etc.
> --
> http://mail.python.org/mailman/listinfo/python-list
>

I decided that I was just trying to be "too smooth by 1/2" so I fell back to
...


messages = open(os.path.join(host_path,'messages.txt'), 'wb')
deliveries = open(os.path.join(host_path,'deliveries.txt'), 'wb')
actions = open(os.path.join(host_path,'actions.txt'), 'wb')
parts = open(os.path.join(host_path,'parts.txt'), 'wb')
recipients = open(os.path.join(host_path,'recipients.txt'), 'wb')
viruses = open(os.path.join(host_path,'viruses.txt'), 'wb')
esp_scores = open(os.path.join(host_path,'esp_scores.txt'), 'wb')


Thank you to everybody who answered.
-- 
http://mail.python.org/mailman/listinfo/python-list

Re: Open a List of Files

2008-01-08 Thread Hrvoje Niksic
Fredrik Lundh <[EMAIL PROTECTED]> writes:

> BJ Swope wrote:
>
>> the code looks ok.  please define "not working".
>>
>> Yep, defining "not working" is always helpful! :)
>>
>> I want to have all 3 files open at the same time.  I will write to
>> each of the files later in my script but just the last file is open
>> for writing.
>
> to keep more than one file open, you need more than one variable, or a
> variable that can hold more than one object.
>
> if the number of files may vary, put the file objects in a list.

Or in a dict:

open_files = {}
for fn in ['messages', 'recipients', 'viruses']:
open_files[fn] = open(getfilename(fn), 'w')

# open_files['messages'] is the open file 'messages' etc.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Open a List of Files

2008-01-08 Thread Fredrik Lundh
BJ Swope wrote:

> the code looks ok.  please define "not working".
> 
> Yep, defining "not working" is always helpful! :)
> 
> I want to have all 3 files open at the same time.  I will write to each 
> of the files later in my script but just the last file is open for writing.

to keep more than one file open, you need more than one variable, or a 
variable that can hold more than one object.

if the number of files may vary, put the file objects in a list.  if the 
number of files is constant, you might as well just use three variables 
and call open three times; e.g.

   def getfilename(name):
 return os.path.join(Host_Path, name)

   messages_file = open(getfilename("messages"), "w")
   recipients_file = open(getfilename("recipients"), "w")
   viruses_file = open(getfilename("viruses"), "w")



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Open a List of Files

2008-01-08 Thread Neil Cerutti
On Jan 8, 2008 6:54 AM, BJ Swope <[EMAIL PROTECTED]> wrote:
> > > given a list such as
> > >
> > > ['messages', 'recipients', 'viruses']
> > >
> > > how would I iterate over the list and use the values as variables and
> > > open the variable names a files?
> > >
> > > I tried
> > >
> > > for outfile in ['messages', 'recipients', 'viruses']:
> > > filename = os.path.join(Host_Path, outfile)
> > > outfile = open(filename, 'w')
> > >
> > > But it's not working.
>
> Yep, defining "not working" is always helpful! :)
>
>  I want to have all 3 files open at the same time.  I will write to each of
> the files later in my script but just the last file is open for writing.

Your code successfully opened them all, but kept a reference only to
the last one.

Try something like:

outfiles = [open(os.path.join(Host_Path, fname), 'w') for fname in fnames]

-- 
Neil Cerutti <[EMAIL PROTECTED]>
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Open a List of Files

2008-01-08 Thread Martin Marcher
BJ Swope wrote:

> On Jan 8, 2008 6:03 AM, Fredrik Lundh <[EMAIL PROTECTED]> wrote:
> 
>> BJ Swope wrote:
>>
>> > given a list such as
>> >
>> > ['messages', 'recipients', 'viruses']
>> >
>> > how would I iterate over the list and use the values as variables and
>> > open the variable names a files?
>> >
>> > I tried
>> >
>> > for outfile in ['messages', 'recipients', 'viruses']:
>> > filename = os.path.join(Host_Path, outfile)
>> > outfile = open(filename, 'w')

files = dict()
l = ['messages', 'recipients', 'viruses']
for f in l:
files[f] = open(s.path.join(Host_Path, outfile), "w")

files["messages].write("a string")

hth
martin

PS: Code is untested

-- 
http://noneisyours.marcher.name
http://feeds.feedburner.com/NoneIsYours

You are not free to read this message,
by doing so, you have violated my licence
and are required to urinate publicly. Thank you.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Open a List of Files

2008-01-08 Thread Chris
On Jan 8, 1:03 pm, Fredrik Lundh <[EMAIL PROTECTED]> wrote:
> BJ Swope wrote:
> > given a list such as
>
> > ['messages', 'recipients', 'viruses']
>
> > how would I iterate over the list and use the values as variables and
> > open the variable names a files?
>
> > I tried
>
> > for outfile in ['messages', 'recipients', 'viruses']:
> > filename = os.path.join(Host_Path, outfile)
> > outfile = open(filename, 'w')
>
> > But it's not working.
>
> the code looks ok.  please define "not working".
>
> 

Bad coding style in that one.  Do you have Write permissions to that
'Host_path' ?

import os, sys

FILELIST = ['messages', 'recipients', 'viruses']
HOST_PATH = os.getcwd()  # Or whatever path you are using

if not os.access(HOST_PATH, os.W_OK):
sys.exit('Unable to write to path specified.')

for file in FILELIST:
output_file = open(os.path.join(HOST_PATH, file), 'wb')
do_something_with_file()


A better definition of not working would be appreciated, Tracebacks if
you have.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Open a List of Files

2008-01-08 Thread BJ Swope
On Jan 8, 2008 6:03 AM, Fredrik Lundh <[EMAIL PROTECTED]> wrote:

> BJ Swope wrote:
>
> > given a list such as
> >
> > ['messages', 'recipients', 'viruses']
> >
> > how would I iterate over the list and use the values as variables and
> > open the variable names a files?
> >
> > I tried
> >
> > for outfile in ['messages', 'recipients', 'viruses']:
> > filename = os.path.join(Host_Path, outfile)
> > outfile = open(filename, 'w')
> >
> > But it's not working.
>
> the code looks ok.  please define "not working".
>
> 
>
> --
> http://mail.python.org/mailman/listinfo/python-list
>

Yep, defining "not working" is always helpful! :)

I want to have all 3 files open at the same time.  I will write to each of
the files later in my script but just the last file is open for writing.
-- 
http://mail.python.org/mailman/listinfo/python-list

Re: Open a List of Files

2008-01-08 Thread John Machin
On Jan 8, 10:03 pm, Fredrik Lundh <[EMAIL PROTECTED]> wrote:
> BJ Swope wrote:
> > given a list such as
>
> > ['messages', 'recipients', 'viruses']
>
> > how would I iterate over the list and use the values as variables and
> > open the variable names a files?
>
> > I tried
>
> > for outfile in ['messages', 'recipients', 'viruses']:
> > filename = os.path.join(Host_Path, outfile)
> > outfile = open(filename, 'w')
>
> > But it's not working.
>
> the code looks ok.  please define "not working".
>

To me, it looks bad. He's rebinding "outfile" inside the loop, which
is not good style, makes the reader slow down, back up, read the code
again ... however this doesn't stop this small code fragment from
opening the 3 files for write access -- assuming an import, and
suitable contents for "Host_Path".
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Open a List of Files

2008-01-08 Thread Fredrik Lundh
BJ Swope wrote:

> given a list such as
> 
> ['messages', 'recipients', 'viruses']
> 
> how would I iterate over the list and use the values as variables and 
> open the variable names a files?
> 
> I tried
> 
> for outfile in ['messages', 'recipients', 'viruses']:
> filename = os.path.join(Host_Path, outfile)
> outfile = open(filename, 'w')
> 
> But it's not working.

the code looks ok.  please define "not working".



-- 
http://mail.python.org/mailman/listinfo/python-list