1

私は自分のゲームの modding API を書いています。ユーザーがゲーム エンジンに、API 関数の 1 つの直前または直後に mod の関数を実行するように指示できるようにしたいと考えています。つまり、関数を「拡張」します。

これまでモッダーは、機能を追加するために関数を書き直さなければなりませんでした。これは、ゲームのソースコードを掘り下げることを意味していました。

現在、次のようなことを考えています。

def moddersFunction():
    pass

myAPI.extendFunction('functionName', 'before-or-after', moddersFunction, extraArgs=[])

これを実装するための比較的クリーンな方法は何でしょうか? myAPI.extendFunctionつまり、あなたがそれを書くとしたら、 の内部はどのようになりますか?

myAPI.extendFunction が関数を追加する辞書を持つことを考えています。API の関数は、mod の関数が設定されている (「登録」されている) 場合にそれをチェックして実行します。しかし、これは、拡張を許可したい modding API のすべての関数で辞書をチェックするコードを追加することを意味します (チェックと関数呼び出し自体を実行する単一の関数呼び出しであっても、それ自体のようです) .

ゲームの API の既存のソースコードを「解体」することなく (誇張しているかもしれませんが)、このような関数の「拡張」を可能にする、巧妙な Python トリックがあるかどうか疑問に思っています。

4

2 に答える 2

2

私は次の行に沿って何かをします:

class hookable(object):
  def __init__(self, fn):
    self.pre = []
    self.post = []
    self.fn = fn
  def add_pre(self, hook):
    self.pre.append(hook)
  def add_post(self, hook):
    self.post.append(hook)
  def __call__(self, *args, **kwargs):
    for hook in self.pre:
      hook(*args, **kwargs)
    ret = self.fn(*args, **kwargs)
    for hook in self.post:
      hook(*args, **kwargs)
    return ret

「拡張可能な」関数は次のように装飾できるようになりました。

@hookable
def square(x):
  return x**2

square.add_pre()と を使用して、square.add_post()への各呼び出しの前後に自動的に呼び出される関数を登録できますsquare()

print square(2)

def pre(x): print 'pre', x
def post(x): print 'post', x

square.add_pre(pre)
print square(2)
print square(3)

square.add_post(post)
print square(4)
print square(5)
于 2013-01-05T18:37:53.090 に答える