0

class Foo:

class Foo():
    def __init__(self):
        del self.foo

    def foo(self):
        pass

インスタンス化されたときraises AttributeError: Foo instance has no attribute 'foo'. ( ) sFooから派生。使用しても役に立ちません。objectclass Foo(object)raiseAttributeError: 'Foo' object attribute 'foo' is read-onlydelattr(self, "foo")

次の操作を行っても、Fooのインスタンスから属性が削除されることはありません。

class Foo():
    def __init__(self):
        self.foo = None
        del self.foo

    def foo(self):
        pass

>>> Foo().foo
<bound method Foo.foo of <__main__.Foo instance at 0x00000000042EA248>>

目的:

私は基本的に、classいくつかの条件が満たされている場合、特定の属性のインスタンスから特定の属性を完全に削除/またはアクセスできないようにしたいと考えています。

助言がありますか?

4

4 に答える 4

1

問題は、削除しようとしているのはメソッドであり、メソッドはインスタンスに保存されず、クラスに保存されることです。

したがって、インスタンスFoo()には実際には属性がありませんfoo。すると、 onFoo().fooが見つかります。属性が on ではないため、on で削除するものはありません。fooFooselfself

クラスがメソッド (または任意のクラス属性)fooを定義している場合、個々のインスタンスからそれを削除する方法はありません。あなたができる最善の方法は、ハッカーを使用し__getattribute__て例外を発生させることです。Fooただし、これにより、すべてのインスタンスのすべての属性アクセスにパフォーマンス ヒットが発生します。

なぜこれを行う必要性を感じますか?

于 2013-07-23T08:32:46.210 に答える
0

fooFooインスタンスの属性ではなく、Foo クラスオブジェクトの属性です。

を使用するFoo().fooと、その行は新しいFooインスタンスを作成し、インスタンスで名前を検索しfooます。インスタンスにはfoo属性がないため、ルックアップはインスタンスのクラス ( Foo. これが、クラス ブロックでバインドされた名前のしくみです。クラス オブジェクトに属性を作成し、このルックアップ フォールバック メカニズムを通じてインスタンスに間接的に影響を与えるだけです。これがまさに通常のメソッド呼び出しの仕組みです。10 個のメソッドと 1000 個のインスタンスを持つクラスの場合、10,000 個のメソッド オブジェクトは必要ありません!

インスタンスの属性を取得する唯一の方法は、 の典型的なパターンのように、インスタンスへの参照を取得した後で、何らかのコードがインスタンスに属性を直接割り当てる場合です。self.name = something__init__

したがって、 を使用して1 つのインスタンスだけdelを取り除く方法はありません。クラスから削除することfooはできますが、それはすべてのインスタンスに影響します。これは、特定のインスタンスを初期化するメソッドに入れる意味はありません。del Foo.foo__init__

fooonを定義することでマスクできselfます。次に、それが優先され、インスタンスごとに異なる可能性があります(ただし、クラスに戻った場合は、再びクラスに戻り始めdelます。または、ジェネリック属性アクセスフックを使用して、いくつかのチェックを行い、場合によってはそうでないかのように動作することもできますまたは、クラス属性として完全に取り除き、不要なときに削除するのではなく、必要なときに各インスタンスに追加することもできます。foofoo__getattribute__foofoo

于 2013-07-23T08:40:02.890 に答える
0

これを試すことができます:

class Foo(object):
 def __init__(self):
  setattr(self,"foo", None)
 def foo(self):
  pass

>>> Foo().foo
>>>
于 2013-07-23T08:40:22.517 に答える