TutorialΒΆ

In the following, we will create a simple class using the different Locker metaclasses to see how they affect the different operations.

First, the OpenLocker metaclass does not prohibit any operations on the instance attributes. Changing attributes, assigning new attributes and/or deleting attributes is permitted.

from fsc.locker import OpenLocker

class Test(metaclass=OpenLocker):
    def __init__(self, x):
        self.x = x

a = Test(1)
a.x = 3 # ok
del a.x # ok
a.y = 3 # ok

The Locker metaclass still allows for changing existing attributes, but the deletion of attributes or creation of new ones is no longer permitted. The behaviour can however be changed by setting the attr_mod_ctrl attribute to a different value.

from fsc.locker import Locker

class Test(metaclass=Locker):
    def __init__(self, x):
        self.x = x

a = Test(1)
a.x = 3 # ok
del a.x # raises AttributeError
a.y = 3 # raises AttributeError

a.attr_mod_ctrl = 'none' # ok
del a.x # ok
a.y = 3 # ok

The ConstLocker metaclass does not allow changing, deleting or creating new attributes. The behaviour can however still be changed by setting the attr_mod_ctrl attribute to a different value.

from fsc.locker import ConstLocker

class Test(metaclass=ConstLocker):
    def __init__(self, x):
        self.x = x

a = Test(1)
a.x = 3 # raises AttributeError
del a.x # raises AttributeError
a.y = 3 # raises AttributeError

a.attr_mod_ctrl = 'none' # ok
del a.x # ok
a.y = 3 # ok

Finally, the SuperConstLocker metaclass does not allow changing, deleting or creating new attributes. Moreover, attr_mod_ctrl cannot be changed.

from fsc.locker import SuperConstLocker

class Test(metaclass=SuperConstLocker):
    def __init__(self, x):
        self.x = x

a = Test(1)
a.x = 3 # raises AttributeError
del a.x # raises AttributeError
a.y = 3 # raises AttributeError

a.attr_mod_ctrl = 'none' # raises AttributeError

For temporarily changing the lock type (via attr_mod_ctrl), the change_lock() Context Manager can be used:

from fsc.locker import ConstLocker, change_lock

class Test(metaclass=ConstLocker):
    def __init__(self, x):
        self.x = x

a = Test(1)

with change_lock(a, 'none'):
    a.x = 3 # ok
    del a.x # ok
    a.y = 3 # ok

a.x = 3 # raises AttributeError
del a.x # raises AttributeError
a.y = 3 # raises AttributeError