Tengo esta clase:

class Foo(object):

    handlers = []

    def __init__(self):
        pass

    def run(self):
        pass

    def foo(self):
        pass

    def bar(self):
        pass

¿Cómo podría implementar el decorador @collect_handler

 class Foo(object):

    handlers = []

    def __init__(self):
        pass

    def run(self):
        pass    

    @collect_handler
    def foo(self):
        pass

    @collect_handler
    def bar(self):
        pass

Para:

foo = Foo()
foo.handlers # [foo, bar]

?

¿es posible?

2
wong2 3 sep. 2014 a las 06:26

2 respuestas

La mejor respuesta
class Foo(object):
    handlers = []
    def collect_handler(handlers):
        def wrapper(func):
            handlers.append(func)
            return func
        return wrapper
    collect_handler = collect_handler(handlers)

    def __init__(self):
        pass

    def run(self):
        pass    

    @collect_handler
    def foo(self):
        pass

    @collect_handler
    def bar(self):
        pass


foo = Foo()
print(foo.handlers)

Rendimientos

[<function foo at 0xb770d994>, <function bar at 0xb770d9cc>]

Estos no son métodos independientes; son simplemente funciones simples. (No se comprueba que el primer argumento sea una instancia de Foo). Sin embargo, deberían ser suficientes. (Tenga en cuenta que en Python3 no hay más métodos independientes; se eliminó la distinción entre métodos independientes y funciones simples).

3
unutbu 3 sep. 2014 a las 02:44

Solo una forma alternativa sin usar decoradores.

f = Foo()
[m for m in dir(f) if getattr(f,m).__doc__ == "COLLECT"]  

La declaración anterior utiliza la comprensión de la lista en Python.
dir es una función incorporada que devolvería todos los atributos de un objeto.
getattr es una función incorporada para recuperar un atributo de un objeto.
__doc__ es una variable de Python que contiene la cadena de documentos para cualquier artefacto de Python.

Esta debería ser tu definición de clase:

class Foo(object):

    def __init__(self):
        pass

    def run(self):
        pass    

    def foo(self):
        "COLLECT"
        pass

    def bar(self):
        "COLLECT"
        pass
0
cppcoder 3 sep. 2014 a las 07:39