[python-nl] Decorator

Schneider f.schneider at de-bleek.demon.nl
Mon May 14 13:13:48 CEST 2012


Ok. Dat klinkt logisch. Kijk ik naar.

 

Frans

 

Van: python-nl-bounces+fs=de-bleek.demon.nl at python.org
[mailto:python-nl-bounces+fs=de-bleek.demon.nl at python.org] Namens Ronald
Oussoren
Verzonden: maandag 14 mei 2012 11:44
Aan: Dutch Python developers and users
Onderwerp: Re: [python-nl] Decorator

 

 

On 14 May, 2012, at 11:25, Schneider wrote:





Dames, heren,

 

Omdat ik weinig ervaring met decorators en multiprocessing heb, ben ik
opzoek naar een beetje hulp.

Ik maak gebruik van CLIPS via PyClips (http://pyclips.sourceforge.net/)
waarbij CLIPS in een apart proces gestart wordt i.v.m. performance e.d. Om
Python aan te kunnen roepen vanuit CLIPS, moeten de Python functies in CLIPS
worden geregistreerd.

Meest basale vorm zonder decorators.

 

import clips

import multiprocessing

 

class CLIPS(object):

    def __init__(self, data):

        self.environment = clips.Environment()

        self.data = data

        clips.RegisterPythonFunction(self.pyprint, "pyprint")

        self.environment.Load("test.clp")

        self.environment.Reset()

        self.environment.Run()

    def pyprint(self, value):

        print self.data, "".join(map(str, value))

 

class CLIPSProcess(multiprocessing.Process):

    def run(self):

        p = multiprocessing.current_process()

        self.c = CLIPS("%s %s" % (p.name, p.pid))

        pass

   

if __name__ == "__main__":

    cp = CLIPSProcess()

    cp.start()

 

Inhoud van test.clp is:

 

(defrule MAIN::start-me-up

       =>

       (python-call pyprint "Hello world")

)                      

 

Output is CLIPSProcess-1 2456 Hello world

Werkt goed. Nu wil ik heel wat "pyprint" achtige functies kunnen registreren
via iets als:

 

    @clips_callable

    def pyprint(self, value):

        .

 

zonder dat ik steeds clips.RegisterPythonFunction hoef aan te roepen. Een
simpele decorator zoals hieronder werkt niet:

 

import clips

import multiprocessing

 

def clips_callable(f):

    from functools import wraps

    @wraps(f)

    def wf(*args, **kwargs):

        print 'calling {}'.format(f.__name__)

        return f(*args, **kwargs)

    clips.RegisterPythonFunction(wf, f.__name__)

    return wf

 

class CLIPS(object):

    def __init__(self, data):

        self.environment = clips.Environment()

        self.data = data

        #clips.RegisterPythonFunction(self.pyprint, "pyprint")

        self.environment.Load("test.clp")

        self.environment.Reset()

        self.environment.Run()

    @clips_callable

    def pyprint(self, value):

        print self.data, "".join(map(str, value))

 

class CLIPSProcess(multiprocessing.Process):

    def run(self):

        p = multiprocessing.current_process()

        self.c = CLIPS("%s %s" % (p.name, p.pid))

        pass

   

if __name__ == "__main__":

    cp = CLIPSProcess()

    cp.start()

 

Met als output

 

calling pyprint

 

De decorator doet duidelijk niet wat ik wil. Heeft iemand misschien een
oplossing?

 

De decorator wordt aangeroepen bij het uitvoeren van de class definitie, dus
voordat CLIPS instantie gemaakt wordt.

 

Om met de decorator hetzelfde gedrag te krijgen als zonder decorator moet je
de de decorator in twee-en splitsen: de decorator zelf markeert de functies
als clips_callable (door ze in een lijstje te plaatsen, of een functie
attribuut toe te voegen), en in __init__ kan je daarna
RegisterPythonFunction aanroepen voor alle functies die je eerder gemarkeerd
hebt.  

 

Als alle "pyprint" functies methoden van de CLIPS klasse zijn zou je ook het
patroon kunnen gebruiken dat in cmd.Cmd in de stdlib gebruikt wordt: geeft
alle CLIPS functies een naam met een specifieke prefix (bijvoorbeeld "def
clips_pyprint(self, value): ...") en maak in __init__ een loop over alle
methoden van de klasse en registreer de methoden waarvan de naam met deze
prefix begint.

 

Ronald

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-nl/attachments/20120514/128ac3c6/attachment-0001.html>


More information about the Python-nl mailing list