2024-10-03 21:32:01 发布
网友
我想在从class A继承class B期间隐藏一些公共方法:
class A
class B
class A(object): def someMethodToHide(): pass def someMethodToShow(): pass class B(A): pass len(set(dir(A)) - set(dir(B))) == 1
如果可能的话,如何用python实现?
Selcuk的suggestion是最好的,但是有时候重构太麻烦了。在
相反,这里有一些东西会让你的同事像女妖一样尖叫,诅咒你的名字。在
它通过使用元类hide_meta来添加重载的__getattribute__和{}方法。只需设置__metaclass__ = hide_meta和{},就可以将其应用到所需的类中。在
hide_meta
__getattribute__
__metaclass__ = hide_meta
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()
您可以创建一个descriptor类来模拟“已删除”属性。然后您可以将“要删除”的名称指定给该类的一个实例。在
下面是一个完整的示例,显示了访问子类上的属性时出现的错误/回溯及其实例。通过引发自定义错误,回溯显式地指示此属性已被故意“删除”。在
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
上面的代码可以在python3.6+上运行。在
下面是我的答案:你可以从第三个类C继承A和B,就像这样:
class C(object): def someMethodToShow(): pass class A(C): def someMethodToHide(): pass class B(C): pass
顺便说一句,如果你想要的是可能的,它将打破多态性。这个不会的
Selcuk的suggestion是最好的,但是有时候重构太麻烦了。在
相反,这里有一些东西会让你的同事像女妖一样尖叫,诅咒你的名字。在
它通过使用元类}方法。只需设置},就可以将其应用到所需的类中。在
hide_meta
来添加重载的__getattribute__
和{__metaclass__ = hide_meta
和{您可以创建一个descriptor类来模拟“已删除”属性。然后您可以将“要删除”的名称指定给该类的一个实例。在
下面是一个完整的示例,显示了访问子类上的属性时出现的错误/回溯及其实例。通过引发自定义错误,回溯显式地指示此属性已被故意“删除”。在
上面的代码可以在python3.6+上运行。在
下面是我的答案:你可以从第三个类C继承A和B,就像这样:
顺便说一句,如果你想要的是可能的,它将打破多态性。这个不会的
相关问题 更多 >
编程相关推荐