MrRadiotron
MrRadiotron

Reputation: 71

python readline() returns multiple lines

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!

Upvotes: 0

Views: 696

Answers (1)

flyer
flyer

Reputation: 9826

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()

Upvotes: 1

Related Questions