3

I'm a python beginner so bear with me. I have written some code on a GUI that allows users to select a file using one button (browse_inputfile), it then displays the file path and then the user can click another button to run a conversion on that file (run_conversion).

However to do this I've had to define a global variable to enable the open file to be passed from one function to another. Is there a better way to do this? I tried passing the path and actually opening it in the second function but this produced "file not found" errors I think due to the "\" used in the string path.

This is the code I have:

def browse_inputfile(self):
       global inputfile
       inputfile = open(QtGui.QFileDialog.getOpenFileName(self, "Open Data File", "", "txt files (*.txt)"),'r+')`

Then there's some code to display the path using "inputfile.name".

The second function is like this:

def run_conversion(self):
   global inputfile     
   if inputfile: # if user didn't pick a file don't continue
      #do stuff
      inputfile.close()

I know using global variables is not good practise, so how can I pass the open file from one function to another and have it so that the user clicks the second button before the "stuff" is run on the file?

I want them to be able to check it's the right file before doing the "stuff" on it.

Thanks

Carmen C
  • 63
  • 1
  • 8
  • The convention is that using global variables is not good practice. I find that statement unreasonable, just because sometimes you just have to use them. Especially in the case where you want to pass your file name in between functions. The thing about globals is that they can be rather dangerous, because of getting confused with duplicate variable names. Good Luck! You are fine as you are in my opinion :) – Damian Chrzanowski Nov 27 '15 at 10:58
  • Thanks Damian. I wondered if that might be the case. However there may be a way to pass the path (as a return? and then a defined variable in the second function) a but I couldn't make it work when I tried without also making that a global variable but I don't know many of the inbuilt python functions so I probably missed something. – Carmen C Nov 27 '15 at 11:22
  • Yes you could pass it on in the function, but that just creates more mess than it is actually worth. Just stick to what you've got for pure convenience's sake. – Damian Chrzanowski Nov 27 '15 at 11:33
  • `browse_inputfile()` and `run_conversion()`are in the same class? – k4ppa Nov 27 '15 at 11:46
  • Yes they are in the same class. – Carmen C Nov 27 '15 at 12:10
  • This is weird. If you can open the file in one place, you should be able to open it elsewhere. Passing the opened file object here is just a dirty workaround when you'd better try to solve the real problem, that is *why you cannot pass the filename*. At least, you should write `inputfilename = QtGui.QFileDialog.getOpenFileName(self, "Open Data File", "", "txt files (*.txt)")` and `inputfile = open(inputfilename,'r+')` and report here the value of `inputfilename` – Serge Ballesta Nov 27 '15 at 13:22
  • Thanks Serge I haven't had time to check it out fully yet.. I think it may be to do with running it on Windows?? Even in the display of the file path which I show to the user the original backslashes were converted to forward slashes, I'm guessing the os then couldn't find the file due to that change. I'm probably doing something wrong there somewhere though. It would be handy to know what I should do for future reference. For now though it's fixed by doing it in a different way and adding it to the class. – Carmen C Nov 27 '15 at 21:12

2 Answers2

0

Your current method risks inputfile not being closed on exit. I would do something like this:

file_path = None

def browse_inputfile(self):
       return QtGui.QFileDialog.getOpenFileName(self, 'Openfile', '/home')

def run_conversion(self, path):    
   if path: # if user didn't pick a file don't continue
      with open(path) as f:
          #do stuff

If you want to manipulate file names robustly, use the functions in the os.path module https://docs.python.org/2/library/os.path.html.

Ben Carr
  • 133
  • 1
  • 5
0

Use inputfile as field of the class, in this way there is no need to pass the file as a parameter or to use a global.

class MyClass:
    def browse_inputfile(self):
        self.inputfile = open(QtGui.QFileDialog.getOpenFileName(self, "Open Data File", "", "txt files (*.txt)"),'r+')`
        # you code for display the path


    def run_conversion(self):
        if self.inputfile: # if user didn't pick a file don't continue
            #do stuff
            self.inputfile.close()
k4ppa
  • 4,122
  • 8
  • 26
  • 36
  • Thanks. This was the sort of thing I was hoping for. It's my first time programming classes since my Coursera course so want to get into the right sort of habits. – Carmen C Nov 27 '15 at 16:42