1

我正在为我的游戏编写一个 modding API,我希望允许用户告诉游戏引擎在其中一个 API 函数之前或之后立即运行他们的 mod 函数,换句话说就是“扩展”这些函数。

在此之前,模组制作者必须重写函数以添加功能,这意味着挖掘游戏的源代码,我认为这对他们来说很糟糕。

现在我在想这样的事情:

def moddersFunction():
    pass

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

现在有什么比较干净的方法来实现这个?换句话说,myAPI.extendFunction如果你写它的内部会是什么样子?

我正在考虑拥有一个字典,myAPI.extendFunction 将向其中添加函数,如果已设置(“注册”),我的 API 中的函数将检查并运行 mod 的函数。但这意味着在我希望允许扩展的修改 API 中的每个函数中添加检查字典的代码(即使它只是一个执行检查和函数调用自身的函数调用,它本身似乎也很重要) .

我想知道是否有一些巧妙的 Python 技巧可以允许这种“扩展”功能而不会“屠杀”(也许我夸大了)我的游戏 API 的现有源代码。

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()andsquare.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 回答
0

我可能会做这样的事情。显然,您实际做的是特定于您的要求。

class Extend(object):
    def __init__(self, original_function):
        self.original_function = original_function

    def __call__(self, function):
        def _wrapped(*args, **kwargs):
            yield function(*args, **kwargs)
            yield self.original_function(*args, **kwargs)
        return _wrapped

import time

@Extend(time.asctime)
def funky_time():
    return "This is the time in the UK"

print list(funky_time())
于 2013-01-05T18:17:39.840 回答