3

このクラスがある場合、変数「値」はクラス変数です。

class Hello:
    value = 10
    def __init__(self):
        print 'init'

オブジェクト 'h' があり、Hello.value と h.value の両方で同じ値 '10' を取得できました。

h = Hello()
print Hello.value
print h.value

このコマンドを実行すると、

h.value = 20

それらを実行すると、値「10」と「20」が得られます。

print Hello.value
print h.value

どうしてこれなの?

  • Q1 : なぜ 'print h.value' は Hello.value の値を出力し、エラーを発生させないのですか?
  • Q2 : h.value = 20 は、「self.value = 20」と同様の新しい変数を導入しますか?
  • Q3 : インスタンス変数の作成を防止する (またはコード 'h.value = 20' の実行を防止する) 方法はありますか?
4

2 に答える 2

4

Pythonでの属性ルックアップの仕組みは次のとおりです。

  1. インスタンスのディクショナリで属性が見つからない場合は、そのクラスのディクショナリで検索され、そこで見つからない場合は、基本クラスのディクショナリでも検索されます。

  2. インスタンス属性に割り当てる場合、これは常にインスタンスにのみ影響します。つまり、属性がインスタンスにすでに存在する場合は属性を更新し、存在しない場合はインスタンスのディクショナリに作成します。

この動作が気に入らない場合は、__setattr__()メソッドを上書きして好きなことを行うことができます。たとえば、インスタンス属性の作成を許可したくない場合はエラーをスローします。後者は__slots__ = []、クラスに追加することによっても達成できます。

于 2011-01-17T23:04:03.087 に答える
4

Pythonが検索する場合o.attr、最初にオブジェクトインスタンスをチェックし、次にそのクラスをチェックし、次に基本クラスをチェックします。これは、メソッドとデータ属性の両方に対して行われます(つまり、データ属性とコード属性の区別はありません)。

割り当て時に、値は常にインスタンスに割り当てられます。それで

  • A1。クラスにフォールバックするため(メソッドは他の方法では機能しないため、クラスにフォールバックする必要があります)

  • A2。はい、そうです。

  • A3。__setattr__ 例外を発生させるメソッドを定義できます。

于 2011-01-17T23:04:46.333 に答える