Python inheritance - how to disable a function Python inheritance - how to disable a function python python

Python inheritance - how to disable a function


There really aren't any true "private" attributes or methods in Python. One thing you can do is simply override the method you don't want in the subclass, and raise an exception:

>>> class Foo( object ):...     def foo( self ):...         print 'FOO!'...         >>> class Bar( Foo ):...     def foo( self ):...         raise AttributeError( "'Bar' object has no attribute 'foo'" )...     >>> b = Bar()>>> b.foo()Traceback (most recent call last):  File "<interactive input>", line 1, in <module>  File "<interactive input>", line 3, in fooAttributeError: 'Bar' object has no attribute 'foo'


kurosch's method of solving the problem isn't quite correct, because you can still use b.foo without getting an AttributeError. If you don't invoke the function, no error occurs. Here are two ways that I can think to do this:

import doctestclass Foo(object):    """    >>> Foo().foo()    foo    """    def foo(self): print 'foo'    def fu(self): print 'fu'class Bar(object):    """    >>> b = Bar()    >>> b.foo()    Traceback (most recent call last):    ...    AttributeError    >>> hasattr(b, 'foo')    False    >>> hasattr(b, 'fu')    True    """    def __init__(self): self._wrapped = Foo()    def __getattr__(self, attr_name):        if attr_name == 'foo': raise AttributeError        return getattr(self._wrapped, attr_name)class Baz(Foo):    """    >>> b = Baz()    >>> b.foo() # doctest: +ELLIPSIS    Traceback (most recent call last):    ...    AttributeError...    >>> hasattr(b, 'foo')    False    >>> hasattr(b, 'fu')    True    """    foo = property()if __name__ == '__main__':    doctest.testmod()

Bar uses the "wrap" pattern to restrict access to the wrapped object. Martelli has a good talk dealing with this. Baz uses the property built-in to implement the descriptor protocol for the attribute to override.


A variation on the answer of kurosch:

class Foo( object ):    def foo( self ):        print 'FOO!'class Bar( Foo ):    @property    def foo( self ):        raise AttributeError( "'Bar' object has no attribute 'foo'" )b = Bar()b.foo

This raises an AttributeError on the property instead of when the method is called.

I would have suggested it in a comment but unfortunately do not have the reputation for it yet.