我知道python函数默认是虚拟的.假设我有这个:
class Foo: def __init__(self, args): do some stuff def goo(): print "You can overload me" def roo(): print "You cannot overload me"
我不希望他们能够做到这一点:
class Aoo(Foo): def roo(): print "I don't want you to be able to do this"
有没有办法防止用户超载roo()?
您可以使用元类:
class NonOverridable(type): def __new__(self, name, bases, dct): if bases and "roo" in dct: raise SyntaxError, "Overriding roo is not allowed" return type.__new__(self, name, bases, dct) class foo: __metaclass__=NonOverridable ...
每当创建子类时,都会调用元类型的new ; 如果您出现,这将导致错误.只有在没有基类的情况下,它才会接受roo的定义.
通过使用注释声明哪些方法是最终的,您可以使方法更加花哨; 然后,您需要检查所有基础并计算所有最终方法,以查看是否有任何基础被覆盖.
这仍然不能阻止某人在定义之后将方法修补到类中; 您可以尝试通过使用自定义词典作为类的字典来捕获这些(这可能不适用于所有Python版本,因为类可能要求类字典具有精确的dict类型).
由于Python有猴子修补,你不仅可以做任何"私人".即使你可以,有人仍然可以在新版本的方法函数中进行monkeypatch.
您可以将此类名称用作"不要靠近"警告.
class Foo( object ): def _roo( self ): """Change this at your own risk."""
这是通常的做法.每个人都可以阅读你的来源.他们被警告了.如果他们大胆地去了他们被警告不去的地方,他们就会得到他们应得的.它不起作用,你无法帮助他们.
您可以尝试使用"私有"方法调用的内部类和"隐藏"实现模块来故意使用此方法.但是......每个人都有你的来源.你不能阻止任何事情.你只能告诉人们他们行为的后果.
def non_overridable(f): f.non_overridable = True return f class ToughMeta(type): def __new__(cls, name, bases, dct): non_overridables = get_non_overridables(bases) for name in dct: if name in non_overridables: raise Exception ("You can not override %s, it is non-overridable" % name) return type.__new__(cls, name, bases, dct) def get_non_overridables(bases): ret = [] for source in bases: for name, attr in source.__dict__.items(): if getattr(attr, "non_overridable", False): ret.append(name) ret.extend(get_non_overridables(source.__bases__)) return ret class ToughObject(object): __metaclass__ = ToughMeta @non_overridable def test1(): pass # Tests --------------- class Derived(ToughObject): @non_overridable def test2(self): print "hello" class Derived2(Derived): def test1(self): print "derived2" # --------------------