Seite 1 von 1

decorator für normale Funktion und Klassen Funktion

Verfasst: Dienstag 12. November 2013, 22:42
von jens
Hab sowas:

Code: Alles auswählen

def pylucid_objects(view_function):
    @wraps(view_function)
    def _inner(request, *args, **kwargs):
        response = resolve_pagetree_url(request)
        if response:
            return response

        # Create initial context object
        request.PYLUCID.context = RequestContext(request)

        return view_function(request, *args, **kwargs)
    return _inner


def class_based_pylucid_objects(view_function):
    @wraps(view_function)
    def _inner(cls, request, *args, **kwargs):
        response = resolve_pagetree_url(request)
        if response:
            return response

        # Create initial context object
        request.PYLUCID.context = RequestContext(request)

        return view_function(cls, request, *args, **kwargs)
    return _inner
Machen beide das selbe, aber der eine ist für normale Funktion und der andere für Klassen Funktion, also bsp:

Code: Alles auswählen

@pylucid_objects
def foo(request):
    pass

class ClassView(object):
    @class_based_pylucid_objects
    def foo(self, request):
        pass
Also beide machen das selbe, aber weil die Signatur anders ist, musste ich zwei machen.
Wie kann man das vereinfachen?

Re: decorator für normale Funktion und Klassen Funktion

Verfasst: Mittwoch 13. November 2013, 01:05
von zikzak
Die Funktion kannst Du Dir sparen, Zugriff über die Klasse (bzw. umgekehrt falls die Klasse sonst nichts hergibt):

Code: Alles auswählen

def dekorierer (f):
    print ("dekoriert")
    return f


class Kongret (object):
    @dekorierer
    @classmethod
    def inner(request, *args, **kwargs):
        print (request, *args, **kwargs)

def funktion (request):
    return Kongret.inner(request)

class Vererbt(Kongret):
    pass
    
a = Kongret()
s = a.inner("über Klasse")
b = funktion("über Funktion")
Kongret.inner("direkt über Methode von Klasse")

v = Vererbt()
v.inner("vererbt")

Re: decorator für normale Funktion und Klassen Funktion

Verfasst: Mittwoch 13. November 2013, 08:31
von jens
Ich verstehe nicht wirklich, wie mir das helfen soll?

Re: decorator für normale Funktion und Klassen Funktion

Verfasst: Mittwoch 13. November 2013, 09:38
von jerch
@jens:
Wenn Du mit vereinfachen meinst, dass Du nur einen Dekorator haben willst - nimm doch `cls` und `request` aus der signatur raus. Dann landen beide in den generischen Parametern (`args` oder `kwargs` je nach Aufruf), da kannst Du sie wieder rausfischen und getrennt behandeln.

Re: decorator für normale Funktion und Klassen Funktion

Verfasst: Mittwoch 13. November 2013, 09:56
von EyDu
Man könnte die Konstruktion zusammenfassen. Die beiden verschiedenen Namen bleiben dabei natürlich noch immer bestehen. Besonders hübsch ist die Lösung aber nicht:

Code: Alles auswählen

def make_function(request_index):
    def function(view_function):
        @wraps(view_function)
        def _inner(*args, **kwargs):
            request = args[request_index]
             
            response = resolve_pagetree_url(request)
            if response:
                return response
        
            # Create initial context object
            request.PYLUCID.context = RequestContext(request)
        
            return view_function(*args, **kwargs)
        return _inner
    return function

pylucid_objects = make_function(0)
class_based_pylucid_objects = make_function(1)