text: Python assign function to dict value - Stack Overflow
  I am trying to write a script that opens files based on dictionary values. For each key/value it opens a file based on that value's name and assigns that file to the name of the value (I think it's going wrong here). So far it opens the files for me, with the right names, so that works. However, I think the name I assign the open(file) function to is wrong, since the rest of my function does not open the files anymore, and I can't close them.
  codeconv={"agt":"r1p1d", "aga":"r2p1d"}
  for value in codeconv.values():
  value=open("c:\Biochemistry\Pythonscripts\Splittest\split"+value+".txt", 'w')
  filelist.append(value)
  "Here I do something with the files"
  So the problem is, how do I assign the open(file) function to the correct name? (Here r1p1d and r2p1d for example) And how do I later call those again?
  AttributeError: 'str'object has no attribute 'close' on the f.close() line.
  EDIT: It now works as I want it to, using the following code: (I also included the 'here I do something' part now just for clarity)
  result=open("C:\\Biochemistry\\Pythonscripts\\Illuminaresults.txt", "r")
  opened_files={}
  for key, value in codeconv.items():
  filename="c:\Biochemistry\Pythonscripts\Splittest\split"+value+".txt"
  file=open(filename, 'w')
  opened_files.update({key: file})
  if line[0:3] in codeconv and len(line)==64:
  f=opened_files[line[0:3]]
  f.write(lastline+line)
  for f in opened_files.values():
  I got another problem now though when I try to write the next part of my script, but that's probably something for another question, as it gives a Windowserror not related to this part. Thanks for the help all!
  python function dictionary share|improve this question edited Dec 22 '10 at 12:45
  Where is filelist declared?
  filelist is declared just before this, I just have filelist=[] in my script
  Don't use file as a variable. It shadows a built-in type.
  If i understand you well, you want to create some variable dynamically from the dictionary so that you can assign them to the opened files, is that it ???!!!!
  I will suggest to do it using another dictionary like this:
  opened_files = {}
  file_name = "c:\Biochemistry\Pythonscripts\Splittest\split%s.txt" % value
  file=open(file_name, 'w')
  you can now access your opened files from the dictionary like this:
  f = opened_files['agt']
  and for you latter code do it like this:
  share|improve this answer edited Dec 22 '10 at 10:43
  answered Dec 22 '10 at 10:23
  You understand correctly yeah. In the 'here I do something part', I want to access my files based on the key in the first dictionary though. You have f=opened_files['r1p1d'] for that, is it possible to do f=opened_files[codeconv['agt']] there?
  @Max: yes sure , i have edited my answer, now i use the dictionary keys rather than the values.
  Dec 22 '10 at 10:44
  If I do this, so:codeconv={"agt":"r1p1d", "aga":"r2p1d"} #expand to all tags opened_files={} for value in codeconv.values(): filename="c:\Biochemistry\Pythonscripts\Splittest\split"+value+".txt" file=open(filename, 'w') opened_files.update({value: file})for f in opened_files.values(): f.close() it still does not properly close the files. Oh and how do I make code in comments less ugly :S
  @Max:what do you mean : it still does not properly close the files ? the file are close, no !!! and i don't think this ugly :) even python namespace are implemented as dictionary so we just did the same here rather than creating variables in the global or local namespace we just created our namespace here ; Hope this can give you a better idea if you don't like it this way :)
  I didn't mean the code itself is ugly, I just mean that the formatting in the comments here is ugly because you can't insert whitespace ;-) and I mean they are not properly closed because if I try to re-open them later, I get an error 'WindowsError: [Error32] The process cannot access the file because it is being used by another process'...
  I'd caution against reusing "value" in that first loop, for clarity and future bugs that might be introduced there. But, the code you posted actually works, so obviously there's something else going on that we can't diagnose here. What you need to do is inspect the contents of filelist before you try to close the file handles in it. That will probably point you towards the answer.
  share|improve this answer answered Dec 22 '10 at 10:14
  That's my exact problem, but I might not have worded it correctly. I don't want to reuse 'value', I want to have the actual value (r1p1d, r2p1d, etc.) be used as the name the open function is assigned to, not to 'value'.
  The contents of filelist after this are: [<open file 'c:\Biochemistry\Pythonscripts\Splittest\splitr1p1d.txt', mode 'w' at 0x0000000002A74540>, <open file 'c:\Biochemistry\Pythonscripts\Splittest\splitr2p1d.txt', mode 'w' at 0x0000000002A746F0>]
  @Max in that case, that AttributeError makes no sense in relation to the code you posted. For what you want to do you probably should just store them in a dictionary as d[value] = open(value, 'w').
  Perhaps you want to append tuples to filelist so the name is associated with the file object
  f=open("c:\Biochemistry\Pythonscripts\Splittest\split"+value+".txt", 'w')
  filelist.append((value, f))
  for name, f in filelist:
  I can't see a problem in your code, maybe it's not in the part pasted? (in filelist, or the snipped bit).
  But anyway, I would rewrite it to avoid using the same variable, value, for two different things:
  for file_id in codeconv.values():
  f = open("c:\Biochemistry\Pythonscripts\Splittest\split"+file_id+".txt", 'w')
  print "WARNING: Expected file handle, got string:", f
  (I also added a bit of troubleshooting code)
  share|improve this answer edited Dec 22 '10 at 10:26
  answered Dec 22 '10 at 10:17
  This would probably work for opening and closing them all, but this does not allow me to call the files later to write in them, only the last one as f is reused all the time, no?
  You can still access the files, in filelist (you don't want to use value or file_id or f (in my version) outside of those loops)
  The files are already open - your filelist object contains open file objects that you can iterate over (for example, with for line_of_text in filelist[0]:) or call other functions of (see dir(file) for other members).
  You can defer opening the file by assigning a lambda and calling it later, for example:
  value2 = lambda: open(complete_filename)
  filelist.append(value2)
  my_file_object = filelist[0]()
  You may prefer to store these in a dictionary:
  for value in codeconv.itervalues():
  filedict[value] = lambda: open(complete_filename)
  my_file_object = filedict["r1p1d"]()
  Or if you really want to create new variables (I strongly recommend not doing this, but since you asked):
  globals()[value] = open(complete_filename)
  #globals()[value] = lambda: open(complete_filename)
  Finally, you close the files as you already are (substituting filedict.itervalues() for filelist if you use a dictionary instead).
  (Obviously you need to replace complete_filename in the above examples with however you calculate the actual filename. I shouldn't need to say this, but I've been stung too often by leaving out these sorts of details.)
  You're not assigning the function, you are assigning the return value. Which appearantly is a string in this case instead of a file object, which is a bit surprising. Are you doing anything with the filelist in the "here I do something" part?
  ok, sounds like you want a dict between key/fileobject (with example usage).
  filedict = {key, open("c:\Biochemistry\Pythonscripts\Splittest\split"+value+".txt", 'w')
  for key, value in codeconv.iteritems()}
  #Here I do something with the files
  filedict["agt"].write("foo")
  filedict["aga"].write("bar")
  for f in filedict.values():
  No, this is everything I do with filelist. In the 'here I do something' part I am trying to do something with the opened files though, which is why they need different names and not be overwritten to 'value' each time.