Seite 1 von 1

Wrapper Klasse für ein Objekt

Verfasst: Samstag 15. August 2009, 02:54
von thomaz
Hi,
weiß jemand wie ich um ein existierendes objekt ein wrapper objekt drumherum legen kann?
Was ich konkret machen will ist den zugriff auf ein object mit einer reihe von (unbekannten) methoden zu kontrollieren (wegen threading.Lock() und so).

Code: Alles auswählen

class KlasseMitNichtBekanntenMethoden():
    def EineMethode(self):
        pass

    def EineAndereMethode(self, args):
        return args


class Wrapper():
    __init__(self, object):
       self.object = object
        #keine ahnung was zu tun ist

    MethodeAufrufen(self, methodenName, args):
        #tue das was ich will
        self.result = self.object.methodenName(args)
        #tue wieder was ich will
        return self.result
        

x = KlasseMitNichtBekanntenMethoden()
y = Wrapper(x)

ergebnis = y.EineAndereMethode(10)

ich hoffe man versteht was ich meine^^

schon ma vielen dank im voraus für eure hilfe
mfg thomaz

Verfasst: Samstag 15. August 2009, 08:28
von HWK
Vielleicht so?

Code: Alles auswählen

from functools import partial

def wrapper(obj, method, *args, **kwargs):
    print 'vorher'
    getattr(obj, method)(*args, **kwargs)
    print 'nachher'

class Wrapper:
    def __init__(self, obj):
        for attr, method in obj.__class__.__dict__.iteritems():
            if callable(method):
                setattr(self, attr, partial(wrapper, obj, attr))

class Test:
    def __init__(self):
        print '__init__'

    def test(self, x, y):
        print 'test: x=%s, y=%s' % (x, y)

if __name__ == '__main__':
    a = Test()
    b = Wrapper(a)
    b.test(5, y=1)
MfG
HWK

Verfasst: Samstag 15. August 2009, 08:31
von tordmor
Oder so:

Code: Alles auswählen

import functools

class KlasseMitNichtBekanntenMethoden():
    def EineMethode(self):
        pass

    def EineAndereMethode(self, args):
        print "EineAndereMethode", args
        return args


class Wrapper():
    def __init__(self, obj):
       self.obj = obj
        #keine ahnung was zu tun ist

    def __getattr__(self, key):
        m = getattr(self.obj, key)
        if callable(m):
            return functools.partial(self.MethodeAufrufen, m)
        else:
            return m

    def MethodeAufrufen(self, methode, *args, **kwargs):
        #tue das was ich will
        self.result = methode(*args, **kwargs)
        #tue wieder was ich will
        return self.result


x = KlasseMitNichtBekanntenMethoden()
y = Wrapper(x)

ergebnis = y.EineAndereMethode(10)
Außerdem: http://www.python.org/dev/peps/pep-0008/

Verfasst: Samstag 15. August 2009, 09:12
von BlackJack
Beide Vorschläge haben das Problem, dass damit nicht nur Methoden gewrappt werden, sondern auch andere Attribute, die "callable" sind.

danke danke danke

Verfasst: Samstag 15. August 2009, 11:47
von thomaz
danke für die schnellen antworten :)
is genau das was ich gesucht habe :D
und des mit den andere attribute, die "callable" sind macht auch nix. is perfekt, genau das was ich gebraucht habe.
hätte ich nie selbst hinbekommen
danke :D

Verfasst: Montag 17. August 2009, 01:22
von str1442
MethodeAufrufen() ist aber nicht notwendig. Das hier reicht schon:

Code: Alles auswählen

from types import MethodType

class Wrapper(object):
    def __init__(self, obj):
        self.obj = obj

    def __getattr__(self, name):
        m = getattr(self.obj, name)
        if isinstance(m, MethodType):
            return m

        raise AttributeError("No method named %s found." % name)
        # Python > 2.6 "No method names {0} found.".format(name)
__getattr__ wird nur dann aufgerufen, wenn ein Attribut nicht auf durch die normale "Lookup"-Hierarchie gefunden wird (Exemplar, dessen Klasse, deren Superklassen). Komplete Wrapper brauchen nur getattr() auf self.obj benutzen.

Verfasst: Montag 17. August 2009, 20:17
von thomaz
@str1442
danke danke

Re: Wrapper Klasse für ein Objekt

Verfasst: Dienstag 18. August 2009, 13:58
von DasIch
thomaz hat geschrieben:weiß jemand wie ich um ein existierendes objekt ein wrapper objekt drumherum legen kann?
Gar nicht, da du aufrufe auf special methods nicht wrappen kannst, die musst du alle implementieren.