如何在Python中隐藏/删除继承类中的一些方法?

2024-10-03 21:32:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我想在从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实现?


Tags: 方法lenobjectdefdirpassclassset
3条回答

Selcuk的suggestion是最好的,但是有时候重构太麻烦了。在

相反,这里有一些东西会让你的同事像女妖一样尖叫,诅咒你的名字。在

它通过使用元类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

顺便说一句,如果你想要的是可能的,它将打破多态性。这个不会的

相关问题 更多 >