I want to hide some public methods during inheritance class B
from class A
:
class A(object):
def someMethodToHide():
pass
def someMethodToShow():
pass
class B(A):
pass
len(set(dir(A)) - set(dir(B))) == 1
How to do it in python if it possible?
Here is the answer form of my comment: You can inherit both A and B from a third class, C. Like that:
class C(object):
def someMethodToShow():
pass
class A(C):
def someMethodToHide():
pass
class B(C):
pass
As a side note, if what you wanted were possible, it would break the polymorphism. This one won't.
You can create a descriptor class for emulating "deleted" attributes. Then you can assign the "to-be-deleted" name an instance of that class.
Here's a full example, showing the errors / tracebacks emerging from access of that attribute on the subclass and an instance thereof. By raising a custom error the traceback explicitly indicates that this attribute has been intentionally "deleted".
In [1]: class DeletedAttributeError(AttributeError):
...: pass
...:
...:
...: class DeletedAttribute:
...: def __set_name__(self, owner, name):
...: self.name = name
...:
...: def __get__(self, instance, owner):
...: cls_name = owner.__name__
...: accessed_via = f'type object {cls_name!r}' if instance is None else f'{cls_name!r} object'
...: raise DeletedAttributeError(f'attribute {self.name!r} of {accessed_via} has been deleted')
...:
...:
...: class Foo:
...: def hide_me(self):
...: pass
...:
...:
...: class Bar(Foo):
...: hide_me = DeletedAttribute()
...:
In [2]: Foo.hide_me
Out[2]: <function __main__.Foo.hide_me(self)>
In [3]: Bar.hide_me
---------------------------------------------------------------------------
DeletedAttributeError Traceback (most recent call last)
<ipython-input-3-240c91cc1fc8> in <module>
----> 1 Bar.hide_me
<ipython-input-1-0f699423deb7> in __get__(self, instance, owner)
10 cls_name = owner.__name__
11 accessed_via = f'type object {cls_name!r}' if instance is None else f'{cls_name!r} object'
---> 12 raise DeletedAttributeError(f'attribute {self.name!r} of {accessed_via!r} has been deleted')
13
14
DeletedAttributeError: attribute 'hide_me' of type object 'Bar' has been deleted
In [4]: Bar().hide_me
---------------------------------------------------------------------------
DeletedAttributeError Traceback (most recent call last)
<ipython-input-4-9653f0da628c> in <module>
----> 1 Bar().hide_me
<ipython-input-1-0f699423deb7> in __get__(self, instance, owner)
10 cls_name = owner.__name__
11 accessed_via = f'type object {cls_name!r}' if instance is None else f'{cls_name!r} object'
---> 12 raise DeletedAttributeError(f'attribute {self.name!r} of {accessed_via!r} has been deleted')
13
14
DeletedAttributeError: attribute 'hide_me' of 'Bar' object has been deleted
The above code works on Python 3.6+.
Selcuk's suggestion is best but sometimes the refactoring is too troublesome.
So instead, here's something that will cause your co-workers to scream like banshees and curse your name.
It works by using a metaclass, hide_meta
, to add overloaded __getattribute__
and __dir__
methods. Its application to the desired class is done by simply setting __metaclass__ = hide_meta
and __excluded__ = ["list", "of", "unwanted", "attributes/methods"]
.
class hide_meta(type):
def __new__(cls, cls_name, cls_bases, cls_dict):
cls_dict.setdefault("__excluded__", [])
out_cls = super(hide_meta, cls).__new__(cls, cls_name, cls_bases, cls_dict)
def __getattribute__(self, name):
if name in cls_dict["__excluded__"]:
raise AttributeError(name)
else:
return super(out_cls, self).__getattribute__(name)
out_cls.__getattribute__ = __getattribute__
def __dir__(self):
return sorted((set(dir(out_cls)) | set(self.__dict__.keys())) - set(cls_dict["__excluded__"]))
out_cls.__dir__ = __dir__
return out_cls
class A(object):
def someMethodToHide(self):
pass
def someMethodToShow(self):
pass
class B(A):
__metaclass__ = hide_meta
__excluded__ = ["someMethodToHide"]
a = A()
print dir(a)
b = B()
print dir(b)
b.someMethodToShow()
b.someMethodToHide()
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