当前位置:  开发笔记 > 编程语言 > 正文

使功能无法覆盖

如何解决《使功能无法覆盖》经验,为你挑选了3个好方法。

我知道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()?



1> Martin v. Lö..:

您可以使用元类:

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类型).


如果我不得不使用你的课,我会恨你的

2> S.Lott..:

由于Python有猴子修补,你不仅可以做任何"私人".即使你可以,有人仍然可以在新版本的方法函数中进行monkeypatch.

您可以将此类名称用作"不要靠近"警告.

class Foo( object ):
    def _roo( self ):
       """Change this at your own risk."""

这是通常的做法.每个人都可以阅读你的来源.他们被警告了.如果他们大胆地去了他们被警告不去的地方,他们就会得到他们应得的.它不起作用,你无法帮助他们.

您可以尝试使用"私有"方法调用的内部类和"隐藏"实现模块来故意使用此方法.但是......每个人都有你的来源.你不能阻止任何事情.你只能告诉人们他们行为的后果.



3> M. Utku ALTI..:
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"

# --------------------

推荐阅读
雯颜哥_135
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有