允许用户“扩展”API函数

时间:2013-01-05 18:13:53

标签: python function

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

之前现在modders必须重写函数来为它添加功能,这意味着要挖掘游戏的源代码,我觉得这些代码很糟糕。

现在我正在考虑这样的事情:

def moddersFunction():
    pass

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

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

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

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

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分: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())