私は独自のバージョンのpygame.Rect矩形を作成しようとしていますが、正方形が特定のワールドバウンドから外れているときに、 。__getattr__(pygame.Rect)を使用するクラスを拡張する
これは私の拡張でpygame.Rectの多くの機能を書き直さなければならなかったことを意味し、それに成功しました。ここに問題はありません。
__getattr__と__setattr__を変更しようとすると問題が発生します。 pygame.Rectはこれらの関数を多用しているので、例えば 'top'や 'bottom'を求めると 'y'と 'y' + 'width'をそれぞれ参照します。私はこれらの関数を自分の機能に合わせて変更しましたが、もう一つ必要なことがあります: __init__関数では、worldwidthとworldheight変数を作成する必要があります。しかし、私はできません。なぜなら、__setattr__関数はそれを許さないからです。ここで
は、私が今持っているものです。
class Rectinworld(pygame.Rect):
'''hides the fact that the world is round, when it comes to collisions and such'''
__slots__ = ['_r']
def __init__(self,(worldwidth,worldheight),*args):
object.__setattr__(self, "worldwidth",worldwidth)
if len(args)==0:
super(Rectinworld, self).__init__((0,0,0,0))
else:
super(Rectinworld, self).__init__(*args)
def __getattr__(self, name):
if name == 'top':
return self._r.y
#etc etc etc
elif name == 'height':
return self._r.h
else:
raise AttributeError(name)
def __setattr__(self, name, value):
if name == 'top' or name == 'y':
self._r.y = value % worldheight
#etc etc etc
elif name == 'height':
if int(value) < 0:
self._ensure_proxy()
self._r.h = int(value)
else:
raise AttributeError(name)
私は明確にするため#etc etc etc
コメントでいくつかのコードを残しました。 pygame.Rectのコードは似ています:__setattr__と__getattr__はworldwidthやworldheightを参照しませんが、そうでなければ同じですが、pygame.Rect .__ init__関数は非常に長いですが、以下のスニペットが最も重要です。
で発見することができます
def __init__(self, *args):
#etc etc etc
if len(args) == 4:
if args[2] < 0 or args[3] < 0:
object.__setattr__(self, '_r', _RectProxy((int(args[0]),
int(args[1]),
int(args[2]),
int(args[3]))))
私は今取得エラーは次のとおりです。
line 10, in __init__
object.__setattr__(self, "worldwidth",0)
AttributeError: 'Rectinworld' object has no attribute 'worldwidth'
明白な修正が__slots__、そこから行くことworldwidthとworldheightを追加しているようです。それはさらに奇妙な誤りをもたらしました。任意の変数を設定しようとしたときには、次のメッセージを与える:
line 65, in __getattr__
raise AttributeError(name)
AttributeError: _r
だから要するに、私の質問は、つまるところ:なぜ私は新しい変数を作成することはできません、と私はできるように、私は、何をすべきかが必要ですか?
スロットと '__setattr__'を使用する必要がありますか? 'self._worldwidth'は使えませんか? – furas
スロットを使用する必要があるかどうかわかりません。私はそれを使用するクラスを拡張しようとしているので、同じスタイルを使用するのが理にかなっています。私は 'top'のような属性を保持したい場合は\ __ setattr__を使用する必要があります。私は 'self._worldwidth'を使うことができますが、これは\ __ setattr__関数では認識されず、AttributeError – user2424345
を私は別のやり方でやっています。私は 'class Rectinworld(object):'の内部に 'self._r = Rect()'を作成し、 '@ property'を使用します。 – furas