2013-01-05 6 views
1

내 게임용 modding API를 작성 중이며 사용자가 API 함수 중 하나 또는 그 직전에 mod 함수를 실행하도록 게임 엔진에 지시 할 수 있습니다. 기능을 "확장"합니다.사용자가 API 함수를 "확장"할 수 있도록 허용

지금까지는 모더스가 게임의 소스 코드를 파헤치는 기능을 추가하기 위해 함수를 다시 작성해야했습니다.

지금 내가 이런 식으로 생각하고 있어요 :

이를 구현하기 위해 비교적 깨끗한 방법이 될 것입니다 무엇을 지금
def moddersFunction(): 
    pass 

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

? 즉, myAPI.extendFunction의 내부 구조는 작성한 것처럼 보이게됩니까?

myAPI.extendFunction이 함수를 추가하고 내 API의 함수가 설정 ("등록")되어있는 경우 mod의 함수를 검사하고 실행하는 사전이 있다고 생각합니다. 그러나 이것은 확장을 허용하고자하는 내 modding API의 모든 단일 함수에서 사전을 검사하는 코드를 추가하는 것을 의미합니다 (심지어 함수 자체를 호출하는 check 및 function을 수행하는 단일 함수 호출이라 할지라도,).

내 게임 API의 기존 소스 코드를 "도살"하지 않고 기능을 "확장"할 수있는 멋진 파이썬 트릭이 있는지 궁금합니다.

+0

대답이 Py3K에만 해당되는 경우 언급하십시오. –

답변

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) 
+0

이 방법은 작동하지 않습니다. 인스턴스 객체 ("self"라고도 함)는 args에 전달되지 않습니다. –

+0

@ user975135 : 명시 적으로 전달하는 것을 방해하는 것이 있습니까? – NPE

+0

무엇을 의미합니까? (방법?) –

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()) 
관련 문제