3

親に存在するサブクラスから属性を削除する方法はありますか?

次の例では

class A(object):
    foo = 1
    bar = 2

class B(A):
    pass

# <desired code here>

b = B()
assert hasattr(b, 'bar') == False

アサーションをパスさせるために記述できるコードはありますか?

4

3 に答える 3

5
class A(object):
    foo = 1
    bar = 2


class B(A):
    @property
    def bar(self):
        raise AttributeError


>>> b = B()
>>> b.bar

Traceback (most recent call last):
  File "<pyshell#17>", line 1, in <module>
    b.bar
  File "<pyshell#15>", line 4, in bar
    raise AttributeError
AttributeError
于 2013-05-25T12:00:21.850 に答える
0

はい、記述子の魔法を使用します。それについては私のブログ記事を参照してください。短縮版:

class nosubclasses(object):
    def __init__(self, f, cls):
        self.f = f
        self.cls = cls
    def __get__(self, obj, type=None):
        if type == self.cls:
            if hasattr(self.f, '__get__'):
                return self.f.__get__(obj, type)
            return self.f
        raise AttributeError

例:

In [2]: class MyClass(object):
   ...:     x = 1
   ...:

In [3]: MyClass.x = nosubclasses(MyClass.x, MyClass)

In [4]: class MySubclass(MyClass):
   ...:     pass
   ...:

In [5]: MyClass.x
Out[5]: 1

In [6]: MyClass().x
Out[6]: 1

In [80]: MySubclass.x
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-80-2b2f456dd101> in <module>()
----> 1 MySubclass.x

<ipython-input-51-7fe1b5063367> in __get__(self, obj, type)
      8                 return self.f.__get__(obj, type)
      9             return self.f
---> 10         raise AttributeError

AttributeError:

In [81]: MySubclass().x
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-81-93764eeb9948> in <module>()
----> 1 MySubclass().x

<ipython-input-51-7fe1b5063367> in __get__(self, obj, type)
      8                 return self.f.__get__(obj, type)
      9             return self.f
---> 10         raise AttributeError

AttributeError:

しかし、コメント投稿者の @delnan が指摘したように、これは Liskov の代用可能性の原則に違反しています。属性がオブジェクト自体を説明していないため、私のブログ投稿の動機は正当なものでした。しかし、一般的に、これはそもそもサブクラス化できるという全体的なポイントを壊します。これは、クラスを持つことの実際の全体的なポイントです。

ちなみに、私の答えと@jamylakの答えの違いは、@jamylakの答えでは、サブクラスごとに属性が削除されることです。を作成した場合class C(A)、属性は引き続き保持されbarます。私の答えでは、クラス自体 (実際には属性) は、サブクラスが属性を持つことを許可しないため、一挙にすべてのサブクラスがそれを持たなくなります。

于 2013-06-12T01:41:13.970 に答える