如何在python中锁定一个方法(防止它被覆盖)?

时间:2015-12-01 13:27:33

标签: python python-2.7

在这个例子中,我想避免# Oops可能性。

def foo():
    return "foo"

class MyClass(object):
    def __init__(self):        
        setattr(self, 'foo', foo)

    def bar(self):
        return "bar"

-

>>> x = MyClass()
>>> x.foo()
>>> x.foo = 2 # Oops    
>>> x.foo()
TypeError: 'int' object is not callable

如何防止我的方法被错误覆盖?

2 个答案:

答案 0 :(得分:2)

使x.foo成为属性,而不指定setter。然而,动态地完成它是非常棘手的:

def add_property(inst, name, method):
    '''
    Adds a property to a class instance.
    Property must be added to the CLASS.
    '''
    cls = type(inst)

    if not hasattr(cls, '__perinstance'):
        cls = type(cls.__name__, (cls,), {})
        cls.__perinstance = True
        inst.__class__ = cls

    setattr(cls, name, property(method))

然后而不仅仅是setattr这样做:

class MyClass(object):
    def __init__(self):
        add_property(self, 'foo', lambda _ : 2)

(为了更实际的使用,请将lambda函数替换为 函数或方法返回foo

的值

输出:

>>> o=MyClass()
>>> o.foo
2
>>> o.foo=3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
>>> 

答案 1 :(得分:1)

您可以检查传递给setattr属性名称是否已经存在于类中(如果需要,还有实例)__dict__并且在这种情况下不要重写它:

class MyClass(object):
    def __setattr__(self, name, value):
        if name not in self.__class__.__dict__ and name not in self.__dict__:
            super(MyClass, self).__setattr__(name, value)

试验:

>>> x = MyClass()
>>> x.foo = foo # equal to your __init__ setattr call
>>> x.foo()
'foo'
>>> x.foo = 2
>>> x.foo()
'foo'
相关问题