Wrapper Klasse für ein Objekt

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
thomaz
User
Beiträge: 16
Registriert: Donnerstag 13. August 2009, 14:31

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
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

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
tordmor
User
Beiträge: 100
Registriert: Donnerstag 20. November 2008, 10:29
Wohnort: Stuttgart

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/
http://www.felix-benner.com
BlackJack

Beide Vorschläge haben das Problem, dass damit nicht nur Methoden gewrappt werden, sondern auch andere Attribute, die "callable" sind.
thomaz
User
Beiträge: 16
Registriert: Donnerstag 13. August 2009, 14:31

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
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

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.
thomaz
User
Beiträge: 16
Registriert: Donnerstag 13. August 2009, 14:31

@str1442
danke danke
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

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.
Antworten