2009-06-19 2 views
3

私は記述子を習得しようとしていますが、オブジェクトの振る舞いで混乱しています。下の2つの例ではわかりましたので、__init__は同じです。誰かが私を納得させない、またはこれを説明するリソースに私を向けることができますか?__init__とクラス変数の設定の違い

import math 
class poweroftwo(object): 
    """any time this is set with an int, turns it's value to a tuple of the int 
    and the int^2""" 
    def __init__(self, value=None, name="var"): 
     self.val = (value, math.pow(value, 2)) 
     self.name = name 

    def __set__(self, obj, val): 
     print "SET" 
     self.val = (val, math.pow(val, 2)) 
    def __get__(self, obj, objecttype): 
     print "GET" 
     return self.val 

class powoftwotest(object): 
    def __init__(self, value): 
     self.x = poweroftwo(value) 

class powoftwotest_two(object): 
    x = poweroftwo(10) 


>>> a = powoftwotest_two() 
>>> b = powoftwotest(10) 
>>> a.x == b.x 
>>> GET 
>>> False #Why not true? shouldn't both a.x and b.x be instances of poweroftwo with the same values? 
+0

出力にタイプ(a.x)とタイプ(b.x)を含めることができます。 –

答えて

3

まず、すべてのクラスにLeadingUpperCaseNamesという名前を付けてください。

>>> a.x 
GET 
(10, 100.0) 
>>> b.x 
<__main__.poweroftwo object at 0x00C57D10> 
>>> type(a.x) 
GET 
<type 'tuple'> 
>>> type(b.x) 
<class '__main__.poweroftwo'> 

a.xは、ディスクリプタをサポートするインスタンスレベルのアクセスです。これは、セクション3.4.2.2で "(いわゆるディスクリプタクラス)が別の新しいスタイルのクラスのクラスディクショナリに現れる"という意味です。 __get__および__set__メソッドを使用するには、クラスディクショナリにインスタンスからアクセスする必要があります。

b.xは、ディスクリプタをサポートしないクラスレベルのアクセスです。

+0

クラスレベルのアクセス*は、ディスクリプタがメタクラス上にある場合、ディスクリプタでサポートすることができます。 –

+0

@EthanFurman:完全に真実ですが、それはこの質問を超えています。そして。私の答えはあまり変わっていませんか? –

+0

最後の行だけです。 (それは私がまだそれを投票した理由です。):) –

関連する問題