Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python inheritance - how to disable a function

In C++ you can disable a function in parent's class by declaring it as private in the child class. How can this be done in Python? I.E. How can I hide parent's function from child's public interface?

like image 965
Boris Gorelik Avatar asked Oct 23 '08 22:10

Boris Gorelik


People also ask

How do you stop inheritance in Python?

The way to "avoid" inheritance here would be to rename _private_var and make it a class-private name. i.e. __private_var . If you do this, running your code will cause an AttributeError: 'Child' object has no attribute '_Parent__private_var' (note the _Parent prefix automatically added).

Can I inherit a function in Python?

Inheritance allows us to define a class that inherits all the methods and properties from another class. Parent class is the class being inherited from, also called base class. Child class is the class that inherits from another class, also called derived class.

Are Classmethod inherited?

Yes, they can be inherited.

Does Python support all inheritance?

Inheritance is a required feature of every object oriented programming language. This means that Python supports inheritance, and as you'll see later, it's one of the few languages that supports multiple inheritance.


2 Answers

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 foo AttributeError: 'Bar' object has no attribute 'foo' 
like image 114
kurosch Avatar answered Oct 04 '22 16:10

kurosch


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 doctest  class 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.

like image 30
cdleary Avatar answered Oct 04 '22 14:10

cdleary