[python] 파이썬에서 후크 나 콜백을 구현하는 가장 좋은 방법은 무엇입니까?


Answers

데코레이터를 사용하는 Aaron의 아이디어와 첨부 된 콜백 목록을 유지하는 클래스에 대한 Ignacio의 아이디어와 C #에서 빌린 개념을 결합하여 다음과 같이 생각해 냈습니다.

class delegate(object):

    def __init__(self, func):
        self.callbacks = []
        self.basefunc = func

    def __iadd__(self, func):
        if callable(func):
            self.__isub__(func)
            self.callbacks.append(func)
        return self

    def callback(self, func):
        if callable(func):
            self.__isub__(func)
            self.callbacks.append(func)
        return func

    def __isub__(self, func):
        try:
            self.callbacks.remove(func)
        except ValueError:
            pass
        return self

    def __call__(self, *args, **kwargs):
        result = self.basefunc(*args, **kwargs)
        for func in self.callbacks:
            newresult = func(result)
            result = result if newresult is None else newresult
        return result

@delegate 사용하여 함수를 @delegate 다른 함수를 함수에 "첨부"할 수 있습니다.

@delegate
def intfactory(num):
    return int(num)

함수는 += (그리고 -= 제거됨)를 사용하여 대리자에 추가 할 수 있습니다. 또한 funcname.callback 을 사용하여 콜백 함수를 추가 할 수 있습니다.

@intfactory.callback
def notify(num):
    print "notify:", num

def increment(num):
    return num+1

intfactory += increment
intfactory += lambda num: num * 2

print intfactory(3)   # outputs 8

이 느낌 Pythonic 있습니까?

Question

나는 나의 모듈 중 하나의 사용자가 사용자의 기능을 호출 할 수있는 인터페이스를 제공하여 기능을 확장 할 수있는 기능을 제공하고자한다. 예를 들어, 클래스의 인스턴스가 생성 될 때 알림을 받고 사용자가 사용하기 전에 인스턴스를 수정할 수있는 기회를 부여 할 수 있습니다.

구현 한 방법은 인스턴스화를 수행하는 모듈 수준의 팩토리 함수를 선언하는 것입니다.

# in mymodule.py
def factory(cls, *args, **kwargs):
    return cls(*args, **kwargs)

그렇다면 mymodule에서 클래스의 인스턴스가 필요할 때 factory(cls, arg1, arg2) 보다는 factory(cls, arg1, arg2) cls(arg1, arg2) 합니다.

이를 확장하기 위해 프로그래머는 다음과 같은 함수를 다른 모듈에 씁니다.

def myFactory(cls, *args, **kwargs):
    instance = myFactory.chain(cls, *args, **kwargs)
    # do something with the instance here if desired
    return instance

위의 콜백 설치는 다음과 같습니다.

myFactory.chain, mymodule.factory = mymodule.factory, myFactory

이것은 나에게 충분히 직설적이지만 파이썬 프로그래머로서 당신이 과제를 수행하는 것보다는 콜백을 등록하기를 기대하거나 다른 방법이 있다면 기대할 수 있습니다. 내 솔루션이 실행 가능하고, 관용적이며, 명확한 것처럼 보입니까?

가능한 한 간단하게 유지하려고합니다. 나는 대부분의 응용 프로그램이 실제로 하나 이상의 사용자 콜백을 연결해야한다고 생각하지 않습니다. 예를 들어 무제한 체인은 위의 패턴으로 "무료"로 제공됩니다. 콜백을 제거하거나 우선 순위를 지정하거나 순서를 지정해야 할 것입니다. python-callbacksPyDispatcher 와 같은 모듈은 과도한 잔인 함, 특히 후자와 같은 것처럼 보이지만, 내 모듈로 작업하는 프로그래머에게 매력적인 이점이 있다면, 나는 그들에게 개방되어있다.




Related