2

__and__基本的に、すべての標準の python int 演算子、たとえば、などにアクセスしたいのですが__xor__、特に結果が最終的に出力されるたびに、16 進形式で表現したいと考えています。(電卓を Hex モードにするようなものです)

class Hex(int):
  def __repr__(self):
    return "0x%x"%self
  __str__=__repr__ # this certainly helps with printing

if __name__=="__main__":
  print Hex(0x1abe11ed) ^ Hex(440720179)
  print Hex(Hex(0x1abe11ed) ^ Hex(440720179))

理想的には、出力の両方の行が 16 進数: 0xfacade である必要がありますが、最初の行は 10 進数: 16435934 になります。

何か案は?

4

5 に答える 5

7

__repr__と を__str__別々に定義する必要があります。

class Hex(int):
  def __repr__(self):
    return "Hex(0x%x)" % self
  def __str__(self):
    return "0x%x" % self

この__repr__関数は、(可能であれば)eval()元のオブジェクトを再構築するために使用できる Python テキストを提供する必要があります。一方、__str__オブジェクトの人間が読める表現を返すことができます。

于 2009-08-07T02:49:45.360 に答える
6

特にPython 2.6以降のクラスデコレータは、多くのメソッドをラップして「スーパークラスのインスタンスではなく、このクラスの型のインスタンスを返す」最も簡単な方法です。これは、他の人が示しているように、根本的な問題です(__str__vsとの口論を超えて__repr__、価値はありますが、問題を解決するものではありません;-)。

def returnthisclassfrom(specials):
  specialnames = ['__%s__' % s for s in specials.split()]
  def wrapit(cls, method):
    return lambda *a: cls(method(*a))
  def dowrap(cls):
    for n in specialnames:
      method = getattr(cls, n)
      setattr(cls, n, wrapit(cls, method))
    return cls
  return dowrap

@returnthisclassfrom('and or xor')
class Hex(int):
  def __repr__(self): return hex(self)
  __str__ = __repr__

a = Hex(2345)
b = Hex(5432)
print a, b, a^b

Python 2.6 では、これは

0x929 0x1538 0x1c11

望んだ通りに。もちろん、デコレーターなどにメソッド名を追加することもできます。Python 2.5 に行き詰まっている場合は、装飾行 ( で始まる行) を削除し、@代わりに使用します

class Hex(int):
  def __repr__(self): return hex(self)
  __str__ = __repr__
Hex = returnthisclassfrom('and or xor')(Hex)

ダニはエレガントではありませんが、同じくらい効果的です;-)

編集:コード内の「通常のスコープの問題」の発生を修正しました。

于 2009-08-07T05:35:09.923 に答える
1

Hex のインスタンスを返すには、演算子 (+、-、​​* など) を取得する必要があります。そのまま、int を返します。

class Hex(int):
    def __repr__(self):
        return "Hex(0x%x)" % self
    def __str__(self):
        return "0x%x" % self
>>> h1 = Hex(100)
>>> h2 = Hex(1000)
>>> h1
Hex(0x64)
>>> h2
Hex(0x3e8)
>>> h1+h2
1100
>>> type(h1+h2)
<type 'int'>

したがって、さまざまな演算子をオーバーライドできます。

class Hex(int):
    def __repr__(self):
        return "Hex(0x%x)" % self
    def __str__(self):
        return "0x%x" % self
    def __add__(self, other):
        return Hex(super(Hex, self).__add__(other))
    def __sub__(self, other):
        return self.__add__(-other)
    def __pow__(self, power):
        return Hex(super(Hex, self).__pow__(power))
    def __xor__(self, other):
        return Hex(super(Hex, self).__xor__(other))

>>> h1 = Hex(100)
>>> h2 = Hex(1000)
>>> h1+h2
Hex(0x44c)
>>> type(h1+h2)
<class '__main__.Hex'>
>>> h1 += h2
>>> h1
Hex(0x44c)
>>> h2 ** 2
Hex(0xf4240)
>>> Hex(0x1abe11ed) ^ Hex(440720179)
>>> Hex(0xfacade)

私はこれについて知りません. Hex???のインスタンスを返すためにすべての演算子をオーバーライドする必要のない、より良い方法があるに違いないと感じています.

于 2009-08-07T03:21:11.067 に答える
1

あなたのコメントに応えて:

自分で Mixin を作成できます。

class IntMathMixin:
    def __add__(self, other):
        return type(self)(int(self).__add__(int(other)))
    # ... analog for the others

次に、次のように使用します。

class Hex(IntMathMixin, int):
    def __repr__(self):
         return "0x%x"%self
    __str__=__repr__ 
于 2009-08-07T04:05:38.763 に答える
0

オーバーライド__str__も。

__repr__repr(o) が呼び出されたときに使用され、対話型プロンプトで値を表示します。 __str__オブジェクトを文字列化するほとんどのインスタンス (出力時を含む) で呼び出されます。

__str__オブジェクトのデフォルトの動作は にフォールバックしますreprint、独自の__str__メソッドを提供します (これは (Python 3 より前の) と同じですが、 にはフォールバック__repr__ません)。__repr__

于 2009-08-07T02:29:09.340 に答える