13

私は pygame でゲームを作成しており、特定のレベルのスプライトを格納することが唯一の仕事である「抽象」クラスを作成しました (これらのレベル オブジェクトをリストに入れ、プレイヤーが 1 つのレベルから移動しやすくすることを目的としています)別のものに)

では、質問に移ります。Pythonでこれと同等のことができる場合(コードはJavaの礼儀):

Object object = new Object (){
    public void overriddenFunction(){
        //new functionality
        };
    };

ゲームでレベルを構築するときよりも、スプライトの移動先に関する情報でコンストラクター (またはレベルの構築を担当するクラス/インスタンス メソッド) をオーバーライドするだけで済みます。ゲームはそれほどエレガントな答えではありません。別の方法として、レベル オブジェクトがインスタンス化されたらレベルを構築し、必要に応じてスプライトを配置するレベル クラス内にメソッドを作成する必要があります。

ですから、よりスタンチな開発者の 1 人が、これがいかにアンチ python であるかについて続ける前に (私はこのサイトを十分に読んで、Python の専門家からその雰囲気を得ることができました)、実行可能かどうか教えてください。

4

3 に答える 3

11

はい、できます!

class Foo:
    def do_other(self):
        print('other!')
    def do_foo(self):
        print('foo!')


def do_baz():
    print('baz!')

def do_bar(self):
    print('bar!')

# Class-wide impact
Foo.do_foo = do_bar
f = Foo()
g = Foo()
# Instance-wide impact
g.do_other = do_baz

f.do_foo()  # prints "bar!"
f.do_other()  # prints "other!"

g.do_foo()  # prints "bar!"
g.do_other()  # prints "baz!"

したがって、スタンチ開発者の 1 人が、これがいかにアンチ python であるかについて語る前に、

この方法で関数を上書きすることは(そうする正当な理由がある場合)、私には合理的にpythonicに思えます。これを行う必要がある理由/方法の 1 つの例は、静的継承が適用されない、または適用されない動的機能がある場合です。

反対のケースは、Zen of Python で見つかる可能性があります。

  • 美しいことは醜いことよりも優れています。
  • 読みやすさが重要です。
  • 実装を説明するのが難しい場合、それは悪い考えです。
于 2013-07-20T00:20:40.087 に答える
5

はい、可能です。ここではfunctools.partial、暗黙のself引数を通常の (非クラス メソッド) 関数に取得するために使用します。

import functools

class WackyCount(object):
    "it's a counter, but it has one wacky method"
    def __init__(self, name, value):
        self.name = name
        self.value = value
    def __str__(self):
        return '%s = %d' % (self.name, self.value)
    def incr(self):
        self.value += 1
    def decr(self):
        self.value -= 1
    def wacky_incr(self):
        self.value += random.randint(5, 9)

# although x is a regular wacky counter...
x = WackyCount('spam', 1)
# it increments like crazy:
def spam_incr(self):
    self.value *= 2
x.incr = functools.partial(spam_incr, x)

print (x)
x.incr()
print (x)
x.incr()
print (x)
x.incr()
print (x)

と:

$ python2.7 wacky.py
spam = 1
spam = 2
spam = 4
spam = 8
$ python3.2 wacky.py    
spam = 1
spam = 2
spam = 4
spam = 8

編集してメモを追加します。これはインスタンスごとのオーバーライドです。これは、Python の属性ルックアップ シーケンスを利用します。xが class のインスタンスである場合K、属性を見つけるために の辞書を調べることからx.attrname始めます。x見つからない場合、次のルックアップは にありKます。すべての通常のクラス関数は、実際にはK.func. したがって、クラス関数を動的に置き換えたい場合は、代わりに @Brian Cane の回答を使用してください。

于 2013-07-20T00:31:12.337 に答える
1

レベルごとに、継承を介して異なるクラスを使用することをお勧めします。

しかし、Python を Java のように扱うことに本当に慣れている場合は、copy.deepcopy() とモンキー パッチからいくらかのマイレージを得ることができます。

于 2013-07-20T00:22:55.687 に答える