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!

6
  • 2
    Why do you want it to be a static method? The problem is calling self in a static method. Commented Jan 14, 2014 at 16:43
  • Your static method uses self; why is it a static method at all if you need access to an attribute of a LockFile instance? Commented Jan 14, 2014 at 16:43
  • You're trying to access self variable inside a static method. That's a hint that the method shouldn't be static IMHO. Commented Jan 14, 2014 at 16:44
  • Are you expecting an earlier instance to be discoverable by the static method? Commented Jan 14, 2014 at 16:44
  • Maybe you really want to look into singleton classes: stackoverflow.com/questions/31875/… Commented Jan 14, 2014 at 16:45

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

Comments

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)

4 Comments

Given that you're changing state, using a class is more semantic than using a model.
What exactly is your use case?
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
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....

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.