Suppose I have two classes, one inheriting from the other :
class A():
def __init__(self):
pass
def doSomething(self):
print('It Works !') # Insert actual code here
class B(A):
pass
How do I make the doSomething method impossible to inherit, so that :
( I want to make the error happen )
>>> a = A()
>>> a.doSomething()
'It Works !'
>>> b = B()
>>> b.doSomething()
Traceback (most recent call last):
File "<pyshell#132>", line 1, in <module>
b.doSomething()
AttributeError: 'B' object has no attribute 'doSomething'
You should question whether you want to have a non-inheritable part in the first place. It would be more typical to abstract out the common parts of A and B into a common parent, or use a mixin pattern.
class Parent
def doCommonThing1
def doCommonThing2
/ \
/ \
/ \
/ \
class A class B
def doSomething def doOtherThing
If you insist that B must be a subclass of A, then the only way to "uninherit" a method is to override it to do something else. For example, a property which raises attribute error is for all practical purposes the same as a missing attribute:
>>> class A:
... def doSomething(self):
... print("it works")
...
>>> class B(A):
... @property
... def doSomething(self):
... msg = "{!r} object has no attribute 'doSomething'"
... raise AttributeError(msg.format(type(self).__name__))
...
>>> A().doSomething()
it works
>>> hasattr(B(), "doSomething")
False
>>> B().doSomething()
...
AttributeError: 'B' object has no attribute 'doSomething'
To the best of my knowledge, there is no builtin way to do this in Python, because it is not really considered part of the Python philosophy. There can define "protected" and "private" methods in Python by prepending a single _ or double __, but you can still call those, it's just discouraged.
One very hacky way to achieve something similar might be to make the method itself "private" and have __getattr__ redirect to that method, but only if the object is really an A.
class A():
def __init__(self):
pass
def __doSomething(self):
print('It Works !')
def __getattr__(self, attr):
if attr == "doSomething":
if type(self) == A:
return self.__doSomething
else:
raise TypeError("Nope")
return super(A).__getattr__(self, attr)
But this could still be circumvented by calling the "private" method directly as _A__doSomething or overwriting __getattr__ in B.
Alternatively, possibly safer and probably simpler (but still pretty hacky IMHO), you could also add that check to doSomething itself.
def doSomething(self):
if type(self) != A:
raise TypeError("Nope")
print('It Works !')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With