10

さまざまなブロックの 2D 配列があり、すべて Block から継承しています。クリックしたブロックが、次のように Dirt タイプのブロックかどうかを確認したい:

clickedblock = getClickedBlock()

if isinstance(clickedblock, Dirt):
    place a block

else:
    don't place a block

isinstanceコードにフォークが作成されるため、これは悪いことであり、避けるべきだと聞いたことがあります。何時isinstanceの利用が良いでしょうか?

私の問題に対するもう1つのより面倒な解決策は、「id」と呼ばれるブロックのフィールドを持ち、それがダートを意味する定数に等しいかどうかを確認することです。しかし、それは非常に悪いように聞こえ、単純なisinstance.

4

4 に答える 4

11

あなたの例は、の正当な使用例のようですisinstance()

それisinstance()は悪いことではありません。多くの場合、ポリモーフィズムを同じ目的で使用できます (その結果、クラスが使用されている場所のコードがよりクリーンになります)。

しかし、時には、isinstance()あなたが必要とするものです。たとえば、変数が文字列かどうかを検出する Pythonic の方法はisinstance(var, basestring).

于 2012-11-29T22:55:42.070 に答える
1

使用したくない場合は、他のオプションがあります。従来のダックタイピングソリューション:

try:
    clickedblock_place = clickedblock.place
except AttributeError:
    # don't place block
else:
    clickedblock_place()

または、次を使用できますhasattr

if hasattr(clickedblock, 'place'):
    clickedblock.place()

たとえば、名前がstrORを指しているかどうかを知る必要がある場合など、継承階層をチェックする(またはダウンしている)場合を除いて、isinstanceを使用することはほとんどありませんunicode

if isinstance(str1, basestring):
    blah, blah, blah
于 2012-11-29T23:31:02.373 に答える
1

私はそれをもっと次のように変更すると思います:

PLACEABLE_TYPES = [ Dirt ]
if isinstance(clickedblock, PLACEABLE_TYPES):
   place the block
else:
   don't place the block

しかし、コメントのアイデア:

if clickedblock.is_placeable(that_place):
    place the block
else:
    don't place the block

メリットもあります。

于 2012-11-29T23:00:59.770 に答える