473,493 Members | 2,229 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Proxy Design Advice Needed

Hello,

I need a way to get a notification whenever a variable of an object
changes. The approach should be non-intrusive so that I can use
existing objects without modifying them.
I want to be notified no matter who or what did change the wrapped
object - even whenever an object internal methods changes the
variables.
So I coded the piece of code shown below (just copy and paste it, it's
ready-to-run).
It's basically a Proxy class that takes an object and whenever somebody
tries to access the proxy, the proxy forwards this to the real object.
Whenever a method of the obj gets called the proxy detects this and the
operation is performed on the the proxy object so that variable change
notifications can be send.
Since I am quite new to Python and the code does not 100% what I want,
I have the feeling, it's not optimal and that there might be a better
way to achieve what I want. For example I am not sure if really all
changes will be catched this way and if the method call re-routed to
proxy object is not a bit hackish. Second, type(Proxy()) doesn't return
the same as type(WrappedObj()). The proxy should behave identical to
the wrapped object. Should I do this with metaclasses to get the type
right or are there better ways? I am not sure if they could fit here or
not.
So, what do you think of this code and how should I improve it?

Thanks a lot for your help!

-Matthias
Code (just copy and pasts and it should run):

import inspect, new, sys

class Proxy(object):
def __init__(self, wrappedObj):
# need to call object here to save objs to our own dict
object.__setattr__(self,'_wrappedObj',wrappedObj)
object.__setattr__(self,'_observers',{})

def __getattribute__(self, name):
# if attribute of proxy obj itself was queried return that
value
if name in ['_wrappedObj','_observers','Subscribe','Notify']:
return object.__getattribute__(self, name)
# otherwise get var from the wrapped object
attr = getattr( object.__getattribute__(self, '_wrappedObj'),
name )
# make method use this proxy object instead of wrapped one to
catch updates
if inspect.ismethod( attr ):
return new.instancemethod( attr.im_func, self,
attr.im_class )
else:
return attr

def __setattr__(self, name, value):
# sets attribute of the wrapped value
setattr(object.__getattribute__(self,'_wrappedObj' ), name,
value)
# notify me of change
object.__getattribute__(self,'Notify')('Changed',n ame, value)

# Adds an observer
def Subscribe(self, function, event = ''):
self._observers.setdefault(event,[]).append(function)

# Notifies all observers
def Notify(self, event = '', *args):
for observer in self._observers.get(event, []):
observer(*args)
class TestObj(object):
classVar = 'cv'
def __init__(self):
self.spam = '1'

def method(self):
self.spam = '2'

# create a proxy
p = Proxy(TestObj())

# print some info of it
print 'Proxy: %s ' % p
print 'Class of proxy: %s' % p.__class__
print 'Type of proxy: %s <--- this sucks' % type(p)
print 'Dir of proxy: %s' % dir(p)

# enable watching changes
p.Subscribe(lambda name, var: sys.stdout.write('%s was changed and is
now %s\n' % (name,var) ) ,'Changed')

# change some stuff
p.method()
p.cv = 'new cv'
p.spam = 1
p.func = lambda x: x-1
print p.func(2)

Jul 19 '05 #1
2 1442

<ni*********@web.de> schrieb im Newsbeitrag
news:11**********************@o13g2000cwo.googlegr oups.com...
Hello,

I need a way to get a notification whenever a variable of an object
changes. The approach should be non-intrusive so that I can use
existing objects without modifying them.
I want to be notified no matter who or what did change the wrapped
object - even whenever an object internal methods changes the
variables.
So I coded the piece of code shown below (just copy and paste it, it's
ready-to-run).
It's basically a Proxy class that takes an object and whenever somebody
tries to access the proxy, the proxy forwards this to the real object.
Whenever a method of the obj gets called the proxy detects this and the
operation is performed on the the proxy object so that variable change
notifications can be send.
Since I am quite new to Python and the code does not 100% what I want,
I have the feeling, it's not optimal and that there might be a better
way to achieve what I want. For example I am not sure if really all
changes will be catched this way and if the method call re-routed to
proxy object is not a bit hackish. Second, type(Proxy()) doesn't return
the same as type(WrappedObj()). The proxy should behave identical to
the wrapped object. Should I do this with metaclasses to get the type
right or are there better ways? I am not sure if they could fit here or
not.
So, what do you think of this code and how should I improve it?

Thanks a lot for your help!

-Matthias
This may be help:

http://aspn.activestate.com/ASPN/Coo.../Recipe/366254

--
Vincent Wehren


Code (just copy and pasts and it should run):

import inspect, new, sys

class Proxy(object):
def __init__(self, wrappedObj):
# need to call object here to save objs to our own dict
object.__setattr__(self,'_wrappedObj',wrappedObj)
object.__setattr__(self,'_observers',{})

def __getattribute__(self, name):
# if attribute of proxy obj itself was queried return that
value
if name in ['_wrappedObj','_observers','Subscribe','Notify']:
return object.__getattribute__(self, name)
# otherwise get var from the wrapped object
attr = getattr( object.__getattribute__(self, '_wrappedObj'),
name )
# make method use this proxy object instead of wrapped one to
catch updates
if inspect.ismethod( attr ):
return new.instancemethod( attr.im_func, self,
attr.im_class )
else:
return attr

def __setattr__(self, name, value):
# sets attribute of the wrapped value
setattr(object.__getattribute__(self,'_wrappedObj' ), name,
value)
# notify me of change
object.__getattribute__(self,'Notify')('Changed',n ame, value)

# Adds an observer
def Subscribe(self, function, event = ''):
self._observers.setdefault(event,[]).append(function)

# Notifies all observers
def Notify(self, event = '', *args):
for observer in self._observers.get(event, []):
observer(*args)
class TestObj(object):
classVar = 'cv'
def __init__(self):
self.spam = '1'

def method(self):
self.spam = '2'

# create a proxy
p = Proxy(TestObj())

# print some info of it
print 'Proxy: %s ' % p
print 'Class of proxy: %s' % p.__class__
print 'Type of proxy: %s <--- this sucks' % type(p)
print 'Dir of proxy: %s' % dir(p)

# enable watching changes
p.Subscribe(lambda name, var: sys.stdout.write('%s was changed and is
now %s\n' % (name,var) ) ,'Changed')

# change some stuff
p.method()
p.cv = 'new cv'
p.spam = 1
p.func = lambda x: x-1
print p.func(2)

Jul 19 '05 #2
Thanks for the hint so far!
The recipe shown there does not exactly what I want though, it doesn't
do the type() stuff and it hooks up every _ variable which could get
crucial if the wrapped object's methods uses them too.

So I think my question boils down to how I can make type(Proxy) return
type(WrappedObject)?

Any hints?

-Matthias

Jul 19 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
7902
by: harry | last post by:
Hi, I have a program that runs on multiple client pc's. Occasionally one or more of those pc's use VPN to connect to another corporate network. When using VPN they need to set proxy server in...
8
3512
by: SpOiLeR | last post by:
Hello! I have a matrix class like this: class MyObject; // MyMatrix is contains MyObjects class MyMatrix { public: ...
0
1054
by: Jeff User | last post by:
Here is what I have and what I would like to do: I am building a web client application. I add a web reference to some web service server to my project so that now I can call the web service. A...
8
3638
by: Joe | last post by:
I have a web service which returns many types (classes) to match the return type. I want to cast the return type to the actual class type. For example: namespace Test { class MyClass { ...
2
2124
by: Jeff User | last post by:
Here is what I have and what I would like to do: I am building a web client application. I add a web reference to some web service server to my project so that now I can call the web service. A...
1
3121
by: FluffyCat | last post by:
This week I've I continued my series of design patterns examples using PHP 5 with the Bridge Pattern and the Flyweight Pattern. Here now is my 19th design pattern example using PHP 5, the Proxy...
7
2229
by: pthomet | last post by:
Another formulation of the message tittle could be : is it really "safe" (in the business sense) to embed a SSL webservice consumer into any given software, given that any time a proxy server will...
9
3442
by: Christian Hackl | last post by:
Hi! I've got a design question related to the combination of the NVI idiom (non-virtual interfaces, ) and popular object-oriented patterns such as Proxy or Decorator, i.e. those which have the...
1
2573
by: George | last post by:
My desktop application (C# 2.0) works just fine and makes tons of requests via WebRequest and WebClient objects. However, users that are behind Proxy servers are not able to use the app. I'm sure...
0
7119
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
6989
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
1
6873
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7367
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5453
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
4889
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4579
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3078
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
285
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.