1

いくつかのサンプル コードをつなぎ合わせようとしていますが、意味がよくわからない部分に遭遇しました。ソース全体を含めずに、重要なセクションと思われるものをターゲットにしようとします。うまくいけば、すべてを取得できます。

ここで、彼はカスタム dict サブクラスを宣言しています。私が考えたのは、クラス変数「customer」と「film」です。(1 つのクラスからこれらを設定すると、すべてのインスタンスでそれらを更新する必要がありますか?)

class Payment(dict):
    customer = film = None

そして、ここで彼は支払いを使用します...

columns = [item[0] for item in cursor.description]
payments = []
for row in cursor.fetchall():
    payment = Payment(zip(columns, row)) #I believe this is where he loads dict items
    payment.customer = customers[payment["customer_id"]] #This is where he assigns 'class variable'
    payment.film = films[payment["film_id"]]
    payments.append(payment)

最後のリストでは、すべての「支払い」が同じ値を持つべきではありませんか (これは別の辞書であることがわかります)。これが私の混乱の原因です。

これら 2 つの属性は全体的に一意の値を持っていることがわかりました。これは Dict のサブクラス化と関係がありますか? 値は参照されているのではなく、コピーされています (技術的にはクラス変数ですが、コピーされているため、一意のままです)。

単純なオブジェクト指向の仕組みを理解したと思ったとき、これは私を投げます...

4

2 に答える 2

4

以下では:

payment.customer = customers[payment["customer_id"]] #This is where he assigns 'class variable'
payment.film = films[payment["film_id"]]

payment.customerとの値は変更していませんpayment.film。代わりに、それらを再バインドして、クラスのインスタンスに固有にします。

次の例を考えてみましょう。

class X(object):
  val = ['orig']

x1 = X()
x2 = X()
x3 = X()
x1.val = ['rebound']      # rebind
x2.val[0] = 'modified'    # modify in place
print x1.val, id(x1.val)
print x2.val, id(x2.val)
print x3.val, id(x3.val)

このプリント

['rebound'] 2907552
['modified'] 2771544
['modified'] 2771544

x1.valリバウンドされた後、どのようにして完全に別個の変数になるかを観察しますが、両方とも同じリストを参照し続けますx2.valx3.val

于 2013-03-12T10:17:49.460 に答える
2

Pythonがオブジェクトの属性を検索するとき、最初にインスタンスを検索し、次にクラスを検索し、次にスーパークラスを検索します。

この後

payment = Payment(zip(columns, row)) #I believe this is where he loads dict items

またはpayment.__dict__のエントリがないことを確認できますcustomerfilm

(getattr)にアクセスしようとするとpayment.film、インスタンスにはfilm属性がないため、が取得されますpayment.__class__.film

属性を常に割り当てると(記述子でない限り)、インスタンスdictにエントリが作成されるため、他のすべてのインスタンスから分離されます。

そして、いくつかの通訳の楽しみ:

>>> class C(dict):
...  foo = "class foo"
... 
>>> c = C()
>>> c.__dict__
{}
>>> c.foo
'class foo'
>>> c.foo = "instance foo"
>>> c.__dict__
{'foo': 'instance foo'}
>>> c.foo
'instance foo'
>>> del c.foo
>>> c.foo
'class foo'

ちなみに、例のコードはこれらのクラス属性にアクセスしないため、これも同様に機能します。

class Payment(dict):
    pass

作者は何らかの理由でそれらの属性を「宣言」することを好むかもしれませんが、この場合、それらをそこに置く必要はありません(そしておそらく混乱させるでしょう)。

于 2013-03-12T10:33:08.417 に答える