473,462 Members | 1,128 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Decorator Maker is working. What do you think?



Ok... it's works! :)

So what do you think?

Look at the last stacked example, it process the preprocess's first in
forward order, then does the postprocess's in reverse order. Which
might be usefull. Interesting in any case.

Making decorators with this class is a snap!

Any thoughts? Any improvements? Any bugs?

Cheers,
Ron_Adam
#---start---
class Decorator(object):
"""
Decorator - A base class to make decorators with.

self.function - the function decorated.
self.arglist - list of arguments of decorator
self.preprocess - over ride to preprocess function arguments.
self.postprocess - over ride to postprocess function
return value.
Example use:
class mydecorator(Decorate):
def self.preprocess(self, args):
# process args
return args
def self.postprocess(self, results):
# process results
return results

deco = mydecorator()

@deco
def function(args):
# function body
return args
"""
def __init__(self):
self.function = None
self.arglist = []
def __call__(self, *arg):
if len(arg) == 1:
arg = arg[0]
self.arglist.append(arg)
def _wrapper(*args):
pre_args = self.preprocess(*args)
if type(pre_args) is not tuple:
pre_args = (pre_args,)
result = self.function(*pre_args)
return self.postprocess(result)
if '<function ' in str(arg):
self.arglist = self.arglist[:-1]
self.function = arg
return _wrapper
return self

def preprocess(self, *args):
#
# Over ride this method.
#
return args

def postprocess(self, result):
#
# Over ride this method.
#
return result
#---1---
class decorator1(Decorator):
def preprocess(self, arg):
newarg = ""
n = 0
darg = list(self.arglist[0])
for a in list(arg):
newarg += a
newarg += darg[n]
n += 1
if n>=len(darg):
n = 0
return newarg
deco1 = decorator1()

@deco1('_-^-')
def test1(text):
return text
print test1('abcdefg')
# a_b-c^d-e_f-g^
#---2---
class decorator2(Decorator):
def postprocess(self, result):
result = result*1.0*self.arglist[0][0]/self.arglist[0][1]
return result
deco2 = decorator2()

@deco2(2,3)
def test2(a):
return a
print test2(7)
# 4.66666666667
#---3---
class decorator3(Decorator):
def preprocess(self, arg1, arg2):
arg1 *= 2
arg2 *= 2
return arg1, arg2
deco3 = decorator3()

@deco3
def test3(a,b):
return a,b
print test3(1,3)
# (2, 6)
#---4---
class decorator4(Decorator):
def postprocess(self, result):
result = int(result/self.arglist[0])
return result
deco4 = decorator4()

@deco4(2)
def test4(n1,n2,n3,n4,n5):
return n1+n2+n3+n4+n5
print test4(1,2,3,4,5)
# 7
#---5---
class decorator5(Decorator):
def preprocess(self, arg):
arg *= 2
print 'Preprocess:',self.arglist[0][0],arg
return arg
def postprocess(self, result):
result *= 2
print 'Postprocess:',self.arglist[0][0],result
return result
deco5a = decorator5()
deco5b = decorator5()
deco5c = decorator5()
deco5d = decorator5()
deco5e = decorator5()

@deco5a('a')
@deco5b('b')
@deco5c('c')
@deco5d('d')
@deco5e('e')
def test5(i):
return i

print test5(10)
# Preprocess: a 20
# Preprocess: b 40
# Preprocess: c 80
# Preprocess: d 160
# Preprocess: e 320
# Postprocess: e 640
# Postprocess: d 1280
# Postprocess: c 2560
# Postprocess: b 5120
# Postprocess: a 10240
# 10240

#---end---
Jul 18 '05 #1
3 2405


Hi again, If anyone is reading this.

Fixed the endless loop when stacking the same decorator instance. You
can now reuse the same exact decorator object either in stacks or on
different functions with different arguments.

The only quirk left is if you stack the same decorator object, and
have arguments on some, but not others. The arguments get processed
first while preprocessing, and last when postprocessing. That
shouldn't be a problem though and is easy to avoid by using an empty
argument lists where they are needed.

Let me know if there are still any problems with it. I know someone
will find this useful.

Cheers,
Ron
(I left off the tests as they were getting to be quite long.)

#---start---

class Decorator(object):
"""
Decorator - A base class to make decorators with.

self.function - the function decorated.
self.arg - argument list passed by decorator
self.preprocess - over ride to preprocess function arguments
self.postprocess - over ride to postprocess function results
"""
def __init__(self):
self.function = None
self.arglist = []
self.arg = None
self._number = 0

def __call__(self, *arg):
if '<function ' in str(arg):
def _wrapper(*args):
try:
self.arg = self.arglist[self._number]
self._number += 1
except IndexError:
self.arg = None
pre_args = self.preprocess(*args)
if type(pre_args) is not tuple:
pre_args = (pre_args,)
result = _wrapper.function(*pre_args)
result = self.postprocess(result)
try:
self._number -= 1
self.arg = self.arglist[self._number-1]
if self._number == 0:
self.arglist = []
self.function = None
self.arg = None
except IndexError:
self.arg = None
return result
_wrapper.function = arg[0]
return _wrapper
self.arglist.append(arg)
return self

def preprocess(self, *args):
#
# Over ride this method.
#
return args

def postprocess(self, result):
#
# Over ride this method.
#
return result

#---end---
Jul 18 '05 #2
Ron_Adam wrote:
Ok... it's works! :)

So what do you think?


Not much. As long as You do not present any nontrivial examples like
Guidos MultiMethod decorator or an implementation of the dispatching
"case" decorator I proposed that would benefit from factoring into pre-
and postprocessing the pattern has only limited use and worse it
suggests a misnomer: it obscures the semantics that is clearly
functional/OO not procedural.

Regards,
Kay

Jul 18 '05 #3
On 5 Apr 2005 00:35:45 -0700, "Kay Schluehr" <ka**********@gmx.net>
wrote:
Ron_Adam wrote:
Ok... it's works! :)

So what do you think?


Not much. As long as You do not present any nontrivial examples like
Guidos MultiMethod decorator or an implementation of the dispatching
"case" decorator I proposed that would benefit from factoring into pre-
and postprocessing the pattern has only limited use and worse it
suggests a misnomer: it obscures the semantics that is clearly
functional/OO not procedural.

Regards,
Kay


No good points at all? :/

Are you saying I need to present a non trivial example such as Guido's
MultiMethod decorator, or the one you proposed?

If I'm not mistaken, there is a difference. Those axamples are
specific applications to solve specific problems using decorator
expressions. While what I'm attempting here is a general purpose
object in which many specific uses could more easily be built with.

What about commonly used trivial cases? As a whole are they not
non-trivial?

How is it limited?

I'm still not sure when, and what type of things, should and should
not be done with decorators.

It seems to me they may be good tools for validating inputs and
outputs, and for getting data on program performance. In those cases,
it would be good to be able to disable them when they aren't needed.

Another use is to redefine a decorator as needed to adapt a function
to a specific input or output. Is that what Guido's multimethod does?

And they might also be used as a way to change the behavior of a group
of related functions all at once at run time in order to save a lot of
code duplication.

I also think they could be abused easily and used when it would be
better to just use a class to do it in the first place.

Cheers,
Ron]
Jul 18 '05 #4

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

Similar topics

24
by: Steven Bethard | last post by:
I think one of the biggest reasons we're having such problems coming to any agreement on decorator syntax is that each proposal makes a number of syntax decisions, not just one. For decorators, I...
7
by: Steven Bethard | last post by:
So here's the state of the decorator debate as I see it: *** Location GvR pretty strongly wants decorators before the function: ...
41
by: John Marshall | last post by:
How about the following, which I am almost positive has not been suggested: ----- class Klass: def __init__(self, name): self.name = name deco meth0: staticmethod def meth0(x):
3
by: Scott David Daniels | last post by:
Over on comp.python.education we were discussing a (generally seen as) misuse of decorators to build the definite integral of a function. On thinking over the definite integral decorator, I had...
22
by: Ron_Adam | last post by:
Hi, Thanks again for all the helping me understand the details of decorators. I put together a class to create decorators that could make them a lot easier to use. It still has a few glitches...
5
by: Doug | last post by:
I am looking at using the decorator pattern to create a rudimentary stored proc generator but am unsure about something. For each class that identifies a part of the stored proc, what if I want to...
9
by: Tyno Gendo | last post by:
Hi I'm trying to learn patterns, which I hope to use in my PHP code, although I'm finding it hard to get any real impression of how patterns fit in properly, I've done the following test code...
4
by: Gerardo Herzig | last post by:
Hi all. Im reading the Gido's aproach using decorators at http://www.artima.com/weblogs/viewpost.jsp?thread=101605 It looks good to me, but the examples shows the functionality using functions....
4
by: thomas.karolski | last post by:
Hi, I would like to create a Decorator metaclass, which automatically turns a class which inherits from the "Decorator" type into a decorator. A decorator in this case, is simply a class which...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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...
0
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
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,...
0
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
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
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

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.