I’m trying to do some defensive programming here to avoid objects changing state in a way that is not easy to debug, so given that in Python the following is possible is there a way to protect Foo.name from being changed so that it forces me to do it more explicitly?
class A(object):
def __init__(self, foo):
self.foo = foo
class B(object):
def __init__(self, foo):
self.foo = foo
def rename(self, new_name):
self.foo.name = new_name
class Foo(object):
def __init__(self, name):
self.name = name
if __name__ == '__main__':
foo = Foo('Fooname')
print 'A foo instance is born and baptized as %s' % foo.name
ainstance = A(foo)
print 'The foo instance is then passed to A and is still called %s' % foo.name
binstance = B(foo)
print 'But then the foo instance is passed to B'
binstance.foo.name = 'Barname'
print 'And in B it is renamed to %s' % foo.name
This outputs:
A foo instance is born and baptized as Fooname
The foo instance is then passed to A and is still called Fooname
But then the foo instance is passed to B
And in B it is renamed to Barname
I know I could implement a method to rename Foo that I could force myself use or that I could use name mangling but this still doesn’t actually prevent me from inadvertently changing foo.name even if it’s called foo._name
You can intercept the setting of arbitrary attributes like this:
That will tell you whenever someone sets any attribute of a
Fooinstance. Obviously you can do whatever you like in__setattr__, up to and including aborting the program if someone sets an attribute at an unexpected time.Properties are a neater way to do this for a single attribute:
but
__setattr__lets you intercept all attribute settings from a single place.