0

我正在尝试在这里进行一些防御性编程,以避免对象以不容易调试的方式更改状态,因此鉴于在 Python 中以下可能有一种方法可以保护 Foo.name 不被更改,以便强制我更明确地做到这一点?

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 

这输出:

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

我知道我可以实现一个重命名 Foo 的方法,我可以强迫自己使用或者我可以使用名称修改,但这实际上仍然不能阻止我无意中更改foo.name,即使它被调用foo._name

4

1 回答 1

3

您可以像这样拦截任意属性的设置:

class Foo(object):
    def __init__(self, name):
        self.name = name

    def __setattr__(self, attrname, value):
        print "Intercepted: " + attrname + " attribute of Foo set to " + value
        super(Foo, self).__setattr__(attrname, value)

每当有人设置Foo实例的任何属性时,它都会告诉您。显然,如果有人在意外时间设置了属性,您可以做任何您喜欢的事情__setattr__,包括终止程序。

属性是对单个属性执行此操作的一种更简洁的方法:

class Foo(object):
    def __init__(self, name):
        self.__name = name

    def getname(self):
        return self.__name

    def setname(self, name):
        print "Intercepted: name attribute of Foo set to " + name
        self.__name = name

    name = property(getname, setname)

__setattr__允许您从一个地方截取所有属性设置。

于 2012-09-03T13:56:50.423 回答