0

I have the following class for creating, writing to and closing a LockFile.

class LockFileManager:
    def __init__(self,fname):
        """
        Create FileLock and Prepender objects.
        """
        self.fname = fname

        self.file_lock = FileLock(fname)
        self.file_lock.acquire()

        self.file_writer = Prepender(fname)

        print "LockFile: File lock and writer acquired!\n"

    @staticmethod
    def add_command(command):
        """
        Prepend a command to the LockFile
        """
        print "LockFile: Adding command: " + command + "\n"
        self.file_writer.write(command)

    def end(self):
        """
        Close and remove the LockFile
        """
        print "LockFile: Closing & Removing LockFile:\n"
        self.file_writer.close()
        self.file_lock.release()

        os.remove(self.fname)

In my main body of code, I would initialise the class like so:

lockfile = LockFileManager("lockfile.txt")

Then elsewhere in my code, I would like to write to the file:

LockFileManager.add_command("Write to LockFile provided at initialisation from some arbitrary point in the code ")

Then at the end of the main body of code, call lockfile.exit()

When I try to add a command, I get NameError occurred: global name 'self' is not defined. If self.file_writer.write(command) is changed to file_writer.write(command) then it does not know what file_writer is.

Does anybody know the proper way to go about this? Cheers!

TomSelleck
  • 6,233
  • 18
  • 71
  • 132

2 Answers2

1

Based on what you said, I believe you're looking for something like this:

from threading import Lock

class LockFile(file):
    def __init__(self, *args, **kwargs):
        super(LockFile, self).__init__(*args, **kwargs)
        self._lock = Lock()

    def write(self, *args, **kwargs):
        with self._lock:
            super(LockFile, self).write(*args, **kwargs)

log_file = LockFile('path/to/logfile', 'w')

Then, simply import log_file in the classes where you will need to write to it.

Joel Cornett
  • 21,725
  • 6
  • 57
  • 82
0

Just realised that a module is probably my best bet, I changed the class to the module below and have achieved the result I wanted

def start(fname):
    """
    Create FileLock and Prepender objects.
    """
    global lockfile_name
    global file_lock
    global file_writer

    lockfile_name = fname

    file_lock = FileLock(fname)
    file_lock.acquire()

    file_writer = Prepender(fname)

    print "LockFile: File lock and writer acquired!\n"


def add_command(command):
    """
    Prepend a command to the LockFile
    """
    print "LockFile: Adding command: " + command + "\n"
    file_writer.write(command)

def end():
    """
    Close and remove the LockFile
    """
    print "LockFile: Closing & Removing LockFile:\n"
    file_writer.close()
    file_lock.release()

    os.remove(self.fname)
TomSelleck
  • 6,233
  • 18
  • 71
  • 132
  • Given that you're changing state, using a class is more semantic than using a model. – Joel Cornett Jan 14 '14 at 17:21
  • What exactly is your use case? – Joel Cornett Jan 14 '14 at 17:25
  • I need to write to a file defined at the beginning of the program. It also has to be locked and text must be pre-pended to it. Some arbitrary classes or modules need to be able to write to it. I imagine it would be very similar to some sort of logger that would write to a pre-determined file – TomSelleck Jan 14 '14 at 17:34
  • 1
    i would recommend you add code to enable you to check cases where `start` is called multiple times... it should throw an exception or something if a lock is active and start is called again.... – Corley Brigman Jan 14 '14 at 18:50