Вместо переопределения удалить метод при расширении класса? - PullRequest
0 голосов
/ 03 августа 2020

Допустим, у меня есть:

 class A:
    def m1(): ...

 class B(A):
   # def m1(): ..doesnt work later, has to be masked
   def m2() :...      

 class C:

    def __init__(..):
       self.ab = <A or B>

    def abc():
       if hasattr(self.ab, 'm1') : ...
       elif hasattr(self.ab, 'm2') : ...

, если я определяю m1 () в B, я переопределяю его. Вместо этого я хочу удалить его или замаскировать таким образом, чтобы hasattr (Bvar, 'm1') возвращал False.

m1 () и m2 () делают разные вещи и не могут делиться name, но у B не должно быть m1 () ...

1 Ответ

3 голосов
/ 03 августа 2020

Вы можете сделать это, реализовав __getattribute__, чтобы вызвать ошибку:

In [1]: class A():
   ...:     def m1(self):
   ...:         return 42
   ...:     def m2(self):
   ...:         return 'foo'
   ...:
   ...: class B(A):
   ...:     def __getattribute__(self, attr):
   ...:         if attr == 'm1':
   ...:             raise AttributeError("Can't access m1 on B object because design is broken")
   ...:         return super().__getattribute__(attr)
   ...:     def m3(self):
   ...:         return 0
   ...:

In [2]: b = B()

In [3]: b.m1()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-3-06964da3db13> in <module>
----> 1 b.m1()

<ipython-input-1-72beff581825> in __getattribute__(self, attr)
      8     def __getattribute__(self, attr):
      9         if attr == 'm1':
---> 10             raise AttributeError("Cant access m1 on B object because design is broken")
     11         return super().__getattribute__(attr)
     12     def m3(self):

AttributeError: Cant access m1 on B object because design is broken

In [4]: b.m2()
Out[4]: 'foo'

In [5]: b.m3()
Out[5]: 0

In [6]: hasattr(b, 'm1')
Out[6]: False

Однако это в основном означает, что B не должен наследовать с A. Ваш дизайн сломан. Это нарушает принцип замены Лисков . Вы почти наверняка должны решить эту проблему, прежде чем полагаться на подобный взлом. Но это возможно.

Будьте осторожны при реализации __getattribute__, потому что легко получить бесконечную рекурсию

...