我正在为我的游戏编写一个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的现有源代码。
答案 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())