如何在Python中隐藏/删除继承类中的某些方法?
我想在继承如何在Python中隐藏/删除继承类中的某些方法?,python,Python,我想在继承类B时从类A隐藏一些公共方法: class A(object): def someMethodToHide(): pass def someMethodToShow(): pass class B(A): pass len(set(dir(A)) - set(dir(B))) == 1 如果可能的话,如何在python中实现它?Selcuk最好,但有时重构太麻烦了 因此,这里有一些东西会让你的同事像女妖一样尖叫,诅咒你的名字 它的工作原理是使用一个元
类B
时从类A
隐藏一些公共方法:
class A(object):
def someMethodToHide():
pass
def someMethodToShow():
pass
class B(A):
pass
len(set(dir(A)) - set(dir(B))) == 1
如果可能的话,如何在python中实现它?Selcuk最好,但有时重构太麻烦了
因此,这里有一些东西会让你的同事像女妖一样尖叫,诅咒你的名字
它的工作原理是使用一个元类,hide\u meta
,来添加重载的\uuuu getattribute\uuuuuu
和\uuuu dir\uuuu
方法。它对所需类的应用只需设置\uuuuuu metaclass\uuuuu=hide\uu meta
和\uuuuuuu excluded\uuuuu=[“列表”、“of”、“不需要的”、“属性/方法”]
以下是我评论的答案形式:您可以从第三个类C继承A和B。如下所示:
class C(object):
def someMethodToShow():
pass
class A(C):
def someMethodToHide():
pass
class B(C):
pass
顺便说一句,如果你想要的是可能的,它将打破多态性。这个不会。您可以创建一个类来模拟“已删除”属性。然后,您可以将“待删除”名称指定给该类的一个实例
下面是一个完整的示例,显示了访问子类及其实例上的该属性时出现的错误/回溯。通过引发自定义错误,回溯明确表示此属性已被故意“删除”
[1]中的:类DeletedAttributeError(AttributeError):
…:通过
...:
...:
…:类DeletedAttribute:
…:def uuu set u name uuuu(self,owner,name):
…:self.name=名称
...:
…:def_uuuget_uuu(self、instance、owner):
…:cls\u name=所有者。\u\u name\u
如果实例不是其他f{cls_name!r}对象,则通过=f'type object{cls_name!r}访问
…:raise DeletedAttributeError(已删除{accessed_via}的f'attribute{self.name!r})
...:
...:
…:类Foo:
…:def hide_me(self):
…:通过
...:
...:
…:类栏(Foo):
…:hide_me=DeletedAttribute()
...:
在[2]中:Foo.hide\u me
出[2]:
在[3]中:Bar.hide\u me
---------------------------------------------------------------------------
DeletedAttributeError回溯(最近一次调用)
在里面
---->1巴。把我藏起来
in\uuuu get\uuuu(self、instance、owner)
10 cls_name=所有者__
11通过=f'type object{cls_name!r}'访问{u,如果实例不是其他f'{cls_name!r}对象'
--->12 raise DeletedAttributeError(通过!r}访问的{u的f'属性{self.name!r}已被删除')
13
14
DeletedAttributeError:已删除对象“Bar”类型的属性“hide_me”
在[4]:Bar()中隐藏我
---------------------------------------------------------------------------
DeletedAttributeError回溯(最近一次调用)
在里面
---->1巴()。隐藏我
in\uuuu get\uuuu(self、instance、owner)
10 cls_name=所有者__
11通过=f'type object{cls_name!r}'访问{u,如果实例不是其他f'{cls_name!r}对象'
--->12 raise DeletedAttributeError(通过!r}访问的{u的f'属性{self.name!r}已被删除')
13
14
DeleteDatTributeTError:“Bar”对象的属性“hide_me”已被删除
上述代码适用于Python 3.6+。删除子类方法的用例是什么?您确定要在这种情况下使用类继承吗?您可以从第三个类C扩展A和B,该类C只有要显示的方法。然后您可以只在类A中实现methodToHide。@Selcuk看起来这是实现它的最简单的方法:)@Ffisegydd是的,因为根本不需要重复代码-不像Java那样需要与代码重复作斗争。但我想我的观点是“为什么您只想从超类部分继承?”如果它只订阅了部分功能,它真的会被认为是一个子类吗?这非常复杂,因为它所提供的价值很小。我认为对同一个问题的回答给出了一个更清晰的解决方案:@BryanOakley,这个答案更简单,但是
NotImplementedError
没有“隐藏”这个方法,它只是使它无法使用。这个答案对于属性也不起作用(无论如何,如果不涉及@property
。@dilbert确实未实现错误不是我要问的。你的解释很好-看起来这是最好的答案!有时需要像您所说的那样编写隐藏方法的诅咒代码。顺便说一句,应该经常使用Seluck解决方案,但有时需要隐藏方法-使用NotImplementedError
进行覆盖是错误的模式,因为错误类型无效,并建议使用其他方法-有效的是AttributeError
。如果没有更好的解决方案,我会尽快给出答案。这是OO设计中最常见的解决方案和有效的模式——我将研究诅咒的解决方案,因为它隐藏了一些方法。
class C(object):
def someMethodToShow():
pass
class A(C):
def someMethodToHide():
pass
class B(C):
pass
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