2017-07-05 19 views
-1

intをサブクラス化して可変にすることはできますか?私はビットのベクトルに素敵なインターフェイスをしようとしてintをサブクラス化して可変にする方法

class CustomBitVector(int): 

    # bit 7 
    @property 
    def seventh_property(self): 
     return bool(self & (1 << 7)) 

    @seventh_property.setter 
    def seventh_property(self, val): 
     self |= bool(val) << 7 

    # bit 6 
    @property 
    def sixth_property(self): 
     return bool(self & (1 << 6)) 

    @sixth_property.setter 
    def sixth_property(self, val): 
     self |= bool(val) << 6 


    # ... a few more of these ... 

    # bit 0 
    @property 
    def zeroth_property(self): 
     return bool(self & (1 << 0)) 

    @zeroth_property.setter 
    def zeroth_property(self, val): 
     self |= bool(val) << 0 

は、以下のクラスを考えてみましょう。私はソケットの独自のプロトコルを読んでいます。私は送受信しているメッセージを表すクラスを作っています。多くの場合、これらのメッセージにはビットベクトルが含まれており、このように扱うのがよいでしょう。

これはすでにビットベクトル値を読み取るのにうまくいきますが、intは不変なので、ビットベクトル値を設定することはできません。

私のようなセッターの1書き換える場合:

@sixth_property.setter 
def sixth_property(self, val): 
    print 'before:', self 
    self |= bool(val) << 6 
    print 'after:', self 

をそれから私は、この動作を取得:

In [2]: c = CustomBitVector() 

In [3]: c.sixth_property 
Out[3]: False 

In [4]: c.sixth_property = True 
before: 0 
after: 64 

In [5]: c 
Out[5]: 0 

In [6]: c.sixth_property 
Out[6]: False 

私は...私はselfに割り当てる代わりに、変更しています私の愚かさを見ることができますそれ。この場合、selfを変更するにはどうすればよいですか?

これを行うには狂気のハックはありますか?たぶん、メタクラスなどを使用していますか?


UPDATE

私は要件を言及するのを忘れてしまった:CustomBitVector

インスタンスは、intのように振る舞う必要があります。特に、私はそれらを渡すことができる必要がありますstruct.pack

+0

整数を変更可能にすることはできません(Cで拡張を記述しない限り)が、拡張する代わりに確実に使用できます。 –

答えて

3

intをサブクラス化して可変にすることは可能ですか?

変更可能なパーツをすべて追加することはできますが、intパーツに触れることはできませんので、追加できる変更の程度はあなたには役立ちません。

代わりに、intサブクラスを使用しないでください。 intを格納する通常のオブジェクトを使用します。あなたが中のため|ため__or____ior__などの追加のメソッドを実装することができます

class IntLike(object): # not IntLike(int): 
    def __init__(self, value=0): 
     self.value = value 
    def __index__(self): 
     return self.value 
    ... 

:あなたはint型のようstruct.packにそれを渡すことができるようにしたい場合は、intとしてあなたのオブジェクトをどのように解釈するかを定義するために__index__メソッドを実装 - 場所、変異体|=。しかしintとの完全な相互運用性のためにあまりにも厳しい努力をしないでください。たとえば、オブジェクトをdictキーとして使用できるようにしないでください。彼らは結局、変更可能です。

クラスがintサブクラスであることが本当に重要な場合は、c.sixth_property = True構文を犠牲にしなければなりません。 c = c.with_sixth_property(True)のような代替案を選択し、非突然変異的に物事を実装する必要があります。

+0

はチャンピオンのように動作します。そして、最も重要なことは、 'struct.pack'でも使用できることです。 – Stephen

関連する問題