0

I think I have created a problem for myself....

I have two functions and a global file descriptor(file object)

def fileController():
    global fd
    fName = ui.fileEdit.text()
    if ui.lineByLine.isChecked:
        ui.fileControl.setText('Next Line')
        ui.fileControl.clicked.connect(nextLine)
    fd = open(fName, 'r')

def nextLine():
    global fd
    lineText = fd.readline()
    print lineText

def main():
    app = QtGui.QApplication(sys.argv)
    global ui
    ui = uiClass()

    ui.fileControl.clicked.connect(fileController)
    ui.lineByLine.stateChanged.connect(lineByLineChange)

    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

when nextLine() is called, it returns the first line.
if it is called again it returns the first line and the second line.
if it is called yet again it returns the first line and the second line and the third line. etc. etc.

could the file descriptor being a global variable cause this?

complete un-redacted code can be found here

all help is appreciated!

EDIT: included more of the code for context
EDIT2: added link to github project file

SOLVED: problem was that:

ui.fileControl.clicked.connect(nextLine)

does not disconnect the previous signal. so every time file Control() was clicked a "signal and slot" was added so that newLine() was called multiple times. And as fileController was still being called the file was being reopened. So I saw the behaviour above. Thanks for all the advice!

MrRadiotron
  • 71
  • 1
  • 7
  • 2
    Post an example interpreter session. (A real one; run the code in the interactive interpreter and copy/paste a transcript.) – user2357112 Dec 04 '13 at 00:57
  • 3
    Your function doesn't return *anything*. – Ignacio Vazquez-Abrams Dec 04 '13 at 00:59
  • Try a generator: [Lazy Method for Reading Big File in Python?](http://stackoverflow.com/questions/519633/lazy-method-for-reading-big-file-in-python)? – Mr. Polywhirl Dec 04 '13 at 00:59
  • It actually runs fine for me. It's probably the code that's calling it that's to blame. – davecom Dec 04 '13 at 01:01
  • @user2357112 in the interactive interpreter it runs fine. So I'll edit the question to show the code around this code. – MrRadiotron Dec 04 '13 at 01:13
  • What's `uiClass`? Or `lineByLineChange`? I expect that somewhere in your program, you're appending to a list when you don't actually want to. – user2357112 Dec 04 '13 at 01:36
  • @IgnacioVazquez-Abrams My function isn't meant to return anything. it prints the line returned by fd.realine() to the console – MrRadiotron Dec 04 '13 at 01:36
  • @user2357112 `uiClass' inherits from `QtGui.QWidget' from PySide. it contains various ui elements, none of which refer to fd. `lineByLineChange' just disables some ui elements when the check box lineByLine is checked. when you say "you're appending to a list when you don't actually want to" what do you mean? the only references to fd and lineText are shown (apart from fd.close() in a clean up function on exit), how could appending a list affect the operation of readline()? – MrRadiotron Dec 04 '13 at 01:48

1 Answers1

1

You could write a class to encapsulate such operations:

class MyFile(object):
    def __init__(self, filename=''):
        self.fp    = open(filename, 'rb')
        self.state = 0 # record the times of 'nextline()' called
        self.total = self.lines_num()

    def lines_num(self):
        """Calculate the total lines of the file"""
        count   = 0
        abuffer = bytearray(2048)
        while self.fp.readinto(abuffer) > 0:
            count += abuffer.count('\n')
        self.fp.seek(0)

        return count

    def nextline(self):
        """Returning -1 means that you have reached the end of the file
        """
        self.state += 1
        lines       = ''
        if self.state <= self.total+1:
            for i in xrange(self.state):
                lines = '%s%s' % (lines, self.fp.readline())
        else:
            return -1
        self.fp.seek(0)

        return lines

>>> test = MyFile('text.txt')
>>> test.nextline()
flyer
  • 9,280
  • 11
  • 46
  • 62
  • Agreed. The use of global variables is a bad idea in general, and an even worse one when it's used to do I/O across multiple functions. – Max Noel Dec 04 '13 at 02:40