Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #16805 > unrolled thread

I love the decorator in Python!!!

Started by88888 Dihedral <dihedral88888@googlemail.com>
First post2011-12-07 23:18 -0800
Last post2011-12-08 15:56 -0800
Articles 20 on this page of 32 — 10 participants

Back to article view | Back to comp.lang.python


Contents

  I love the decorator in Python!!! 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-07 23:18 -0800
    Re: I love the decorator in Python!!! Chris Rebert <clp2@rebertia.com> - 2011-12-08 00:04 -0800
    Re: I love the decorator in Python!!! Thomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de> - 2011-12-08 09:59 +0100
      Re: I love the decorator in Python!!! Chris Angelico <rosuav@gmail.com> - 2011-12-08 20:37 +1100
      Re: I love the decorator in Python!!! K.-Michael Aye <kmichael.aye@gmail.com> - 2011-12-08 12:22 +0100
        Re: I love the decorator in Python!!! Francesco Bochicchio <bieffe62@gmail.com> - 2011-12-09 04:00 -0800
      Re: I love the decorator in Python!!! Chris Angelico <rosuav@gmail.com> - 2011-12-08 22:43 +1100
        Re: I love the decorator in Python!!! Thomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de> - 2011-12-09 10:57 +0100
        Re: I love the decorator in Python!!! 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-09 10:28 -0800
          Re: I love the decorator in Python!!! 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-09 16:21 -0800
          Re: I love the decorator in Python!!! 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-09 16:21 -0800
            Re: I love the decorator in Python!!! 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-10 06:04 -0800
              Re: I love the decorator in Python!!! 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-10 06:09 -0800
                Re: I love the decorator in Python!!! alex23 <wuwei23@gmail.com> - 2011-12-11 19:35 -0800
              Re: I love the decorator in Python!!! 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-10 06:09 -0800
            Re: I love the decorator in Python!!! 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-10 06:04 -0800
        Re: I love the decorator in Python!!! 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-09 10:28 -0800
      Re: I love the decorator in Python!!! K.-Michael Aye <kmichael.aye@gmail.com> - 2011-12-08 17:24 +0100
      Re: I love the decorator in Python!!! Chris Angelico <rosuav@gmail.com> - 2011-12-09 03:38 +1100
        Re: I love the decorator in Python!!! alex23 <wuwei23@gmail.com> - 2011-12-08 21:02 -0800
          Re: I love the decorator in Python!!! Robert Kern <robert.kern@gmail.com> - 2011-12-09 10:08 +0000
            Re: I love the decorator in Python!!! alex23 <wuwei23@gmail.com> - 2011-12-11 19:36 -0800
              Re: I love the decorator in Python!!! 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-11 20:51 -0800
                Re: I love the decorator in Python!!! alex23 <wuwei23@gmail.com> - 2011-12-11 21:47 -0800
                  Re: I love the decorator in Python!!! 88888 Dihedral <dihedral88888@googlemail.com> - 2011-12-12 04:16 -0800
              Re: I love the decorator in Python!!! Ethan Furman <ethan@stoneleaf.us> - 2011-12-11 23:47 -0800
              Re: I love the decorator in Python!!! Robert Kern <robert.kern@gmail.com> - 2011-12-12 16:27 +0000
                Re: I love the decorator in Python!!! alex23 <wuwei23@gmail.com> - 2011-12-12 16:46 -0800
      Re: I love the decorator in Python!!! Andrew Berg <bahamutzero8825@gmail.com> - 2011-12-08 10:54 -0600
      Re: I love the decorator in Python!!! Andrew Berg <bahamutzero8825@gmail.com> - 2011-12-08 10:55 -0600
      Re: I love the decorator in Python!!! Ethan Furman <ethan@stoneleaf.us> - 2011-12-08 15:34 -0800
      Re: I love the decorator in Python!!! Ethan Furman <ethan@stoneleaf.us> - 2011-12-08 15:56 -0800

Page 1 of 2  [1] 2  Next page →


#16805 — I love the decorator in Python!!!

From88888 Dihedral <dihedral88888@googlemail.com>
Date2011-12-07 23:18 -0800
SubjectI love the decorator in Python!!!
Message-ID<29996186.628.1323328726122.JavaMail.geo-discussion-forums@prfb7>
I use the @ decorator to behave exactly like a c macro that 
does have fewer side effects. 

I am wondering is there other interesting methods to do the 
jobs in Python?

A lot people complained that no macro in Python. 

Cheers to the rule of Python :
If there's none then just go ahead and  build one!

[toc] | [next] | [standalone]


#16810

FromChris Rebert <clp2@rebertia.com>
Date2011-12-08 00:04 -0800
Message-ID<mailman.3398.1323331470.27778.python-list@python.org>
In reply to#16805
On Wed, Dec 7, 2011 at 11:18 PM, 88888 Dihedral
<dihedral88888@googlemail.com> wrote:
> I use the @ decorator to behave exactly like a c macro that
> does have fewer side effects.
>
> I am wondering is there other interesting methods to do the
> jobs in Python?

* Class decorators (http://www.python.org/dev/peps/pep-3129/ ); i.e.
using decorators on a class instead of a function/method
* Metaclasses (http://docs.python.org/dev/reference/datamodel.html#customizing-class-creation
); a rather more complicated feature capable of serious black magic
* Descriptors (http://docs.python.org/dev/reference/datamodel.html#implementing-descriptors
); probably the most rarely directly used of the three

Cheers,
Chris
--
http://rebertia.com

[toc] | [prev] | [next] | [standalone]


#16812

FromThomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de>
Date2011-12-08 09:59 +0100
Message-ID<jbpu9j$1af$1@r03.glglgl.gl>
In reply to#16805
Am 08.12.2011 08:18 schrieb 88888 Dihedral:
> I use the @ decorator to behave exactly like a c macro that
> does have fewer side effects.
>
> I am wondering is there other interesting methods to do the
> jobs in Python?

In combination with a generator, you can do many funny things.


For example, you can build up a string:

def mkstring(f):
     """Turns a string generator into a string,
     joining with ", ".
     """
     return ", ".join(f())

def create_answer():
     @mkstring
     def people():
         yield "Anna"
         yield "John"
         yield "Theo"

     return "The following people were here: " + people


Many other things are thinkable...


Thomas

[toc] | [prev] | [next] | [standalone]


#16815

FromChris Angelico <rosuav@gmail.com>
Date2011-12-08 20:37 +1100
Message-ID<mailman.3399.1323337078.27778.python-list@python.org>
In reply to#16812
On Thu, Dec 8, 2011 at 7:59 PM, Thomas Rachel
<nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de>
wrote:
> Many other things are thinkable...

And many more are unthinkable. Can we start an International
Obfuscated Python Code Contest? It's the only place such...
abhorrences can properly flourish.

ChrisA

[toc] | [prev] | [next] | [standalone]


#16821

FromK.-Michael Aye <kmichael.aye@gmail.com>
Date2011-12-08 12:22 +0100
Message-ID<mailman.3405.1323343364.27778.python-list@python.org>
In reply to#16812
On 2011-12-08 08:59:26 +0000, Thomas Rachel said:

> Am 08.12.2011 08:18 schrieb 88888 Dihedral:
>> I use the @ decorator to behave exactly like a c macro that
>> does have fewer side effects.
>> 
>> I am wondering is there other interesting methods to do the
>> jobs in Python?
> 
> In combination with a generator, you can do many funny things.
> 
> 
> For example, you can build up a string:
> 
> def mkstring(f):
>      """Turns a string generator into a string,
>      joining with ", ".
>      """
>      return ", ".join(f())
> 
> def create_answer():
>      @mkstring
>      def people():
>          yield "Anna"
>          yield "John"
>          yield "Theo"
> 
>      return "The following people were here: " + people
> 
> 
> Many other things are thinkable...
> 
> 
> Thomas

I am still perplexed about decorators though, am happily using Python 
for many years without them, but maybe i am missing something?
For example in the above case, if I want the names attached to each 
other with a comma, why wouldn't I just create a function doing exactly 
this? Why would I first write a single name generator and then decorate 
it so that I never can get single names anymore (this is the case, 
isn't it? Once decorated, I can not get the original behaviour of the 
function anymore.
So, above, why not
def mkstring(mylist):
with the same function declaration and then just call it with a list of 
names that I generate elsewhere in my program?
I just can't identify the use-case for decorators, but as I said, maybe 
I am missing something.

Michael

[toc] | [prev] | [next] | [standalone]


#16911

FromFrancesco Bochicchio <bieffe62@gmail.com>
Date2011-12-09 04:00 -0800
Message-ID<8e5b46e4-86a9-4192-ac99-7872d08677fc@x7g2000yqb.googlegroups.com>
In reply to#16821
On 8 Dic, 12:22, K.-Michael Aye <kmichael....@gmail.com> wrote:
> On 2011-12-08 08:59:26 +0000, Thomas Rachel said:
>
>
>
> > Am 08.12.2011 08:18 schrieb 88888 Dihedral:
> >> I use the @ decorator to behave exactly like a c macro that
> >> does have fewer side effects.
>
> >> I am wondering is there other interesting methods to do the
> >> jobs in Python?
>
> > In combination with a generator, you can do many funny things.
>
> > For example, you can build up a string:
>
> > def mkstring(f):
> >      """Turns a string generator into a string,
> >      joining with ", ".
> >      """
> >      return ", ".join(f())
>
> > def create_answer():
> >      @mkstring
> >      def people():
> >          yield "Anna"
> >          yield "John"
> >          yield "Theo"
>
> >      return "The following people were here: " + people
>
> > Many other things are thinkable...
>
> > Thomas
>
> I am still perplexed about decorators though, am happily using Python
> for many years without them, but maybe i am missing something?
> For example in the above case, if I want the names attached to each
> other with a comma, why wouldn't I just create a function doing exactly
> this? Why would I first write a single name generator and then decorate
> it so that I never can get single names anymore (this is the case,
> isn't it? Once decorated, I can not get the original behaviour of the
> function anymore.
> So, above, why not
> def mkstring(mylist):
> with the same function declaration and then just call it with a list of
> names that I generate elsewhere in my program?
> I just can't identify the use-case for decorators, but as I said, maybe
> I am missing something.
>
> Michael

I had/have similar feelings. For instance,  this is something that I
tought useful, but then I never used in real code.
The idea was to find a way to automate this code pattern, which I do a
lot:

class SomeClass:
   def __init__(self, some, attribute, here ):
       self.some, self.attribute, self.here = some, attribute, here


In other words, I often define classes in which the constructor list
of arguments corresponds one-to-one to class attributes.
So I thought of this (it uses class decorators so it only works with
Python 3.x ) :


class FieldsDecorator:
    def __init__(self, *names):
        self.names = names

    def __call__(self, cls):
        def constructor(instance, **kwds):
            for n,v in kwds.items():
                if n in self.names:
                    setattr(instance, n, v)
                else: raise TypeError("%s is not a valid field" % s )
        setattr(cls, '__init__', constructor )
        return cls


@FieldsDecorator("uno", "due")
class Prova:
    pass

p = Prova(uno=12, due=9)
print (p.uno, p.due )


It works and it is nice, but I don't find it compelling enough to use
it. I keep assigning directly the attributes, which is more readable.

Decorators are really useful when you have lot of repetitive
boilercode that you _want_ to hide,  since it has little to do with
the problem logic and more to to with the technicalities of the
programming language or of some framework that you are using. It is
called "separating of concerns" I think, and is one of the principles
of Aspect-Oriented Programming (and  with decorators you can do some
nice AOP exercises ... ).

Ciao
---
FB

[toc] | [prev] | [next] | [standalone]


#16823

FromChris Angelico <rosuav@gmail.com>
Date2011-12-08 22:43 +1100
Message-ID<mailman.3408.1323344595.27778.python-list@python.org>
In reply to#16812
On Thu, Dec 8, 2011 at 10:22 PM, K.-Michael Aye <kmichael.aye@gmail.com> wrote:
> I am still perplexed about decorators though, am happily using Python for
> many years without them, but maybe i am missing something?
> For example in the above case, if I want the names attached to each other
> with a comma, why wouldn't I just create a function doing exactly this? Why
> would I first write a single name generator and then decorate it so that I
> never can get single names anymore (this is the case, isn't it? Once
> decorated, I can not get the original behaviour of the function anymore.

The example given is a toy. It's hardly useful. However, there are a
number of handy uses for decorators; mostly, they consist of giving a
single simple keyword to a complicated set of logic. One example is
the @classmethod and @staticmethod decorators - the code to implement
them could be uglier than nested inline assembly, but you don't have
to care, because you just type "@staticmethod" in front of your def
statement and it does its magic.

Here's a handy trick that I'm sure someone has done in a more sophisticated way:

def trace(func):
    if debugmode:
        return lambda *a,**ka:
(print(">"+func.__name__),func(*a,**ka),print("<"+func.__name__))[1]
    return func

Then you put @trace in front of all your functions, and if debugmode
is False, nothing will be done - but set it to true, and you get
console output at the entry and exit of each function.

>>> @trace
def test(x):
	print("Test! "+x)
	return 5

>>> test("asdf")
>test
Test! asdf
<test
5

Again, it's helpful because it condenses all the logic (including the
'debugmode' flag) down to a single high level directive: "Trace this
function".

ChrisA

[toc] | [prev] | [next] | [standalone]


#16903

FromThomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de>
Date2011-12-09 10:57 +0100
Message-ID<jbsm3c$qj1$1@r03.glglgl.gl>
In reply to#16823
Am 08.12.2011 12:43 schrieb Chris Angelico:
> On Thu, Dec 8, 2011 at 10:22 PM, K.-Michael Aye<kmichael.aye@gmail.com>  wrote:
>> I am still perplexed about decorators though, am happily using Python for
>> many years without them, but maybe i am missing something?
>> For example in the above case, if I want the names attached to each other
>> with a comma, why wouldn't I just create a function doing exactly this? Why
>> would I first write a single name generator and then decorate it so that I
>> never can get single names anymore (this is the case, isn't it? Once
>> decorated, I can not get the original behaviour of the function anymore.
>
> The example given is a toy. It's hardly useful.

Right. It was supposed to be an example.

In my case, I work with a script used to build a XML file. I change this 
script from time to time in order to match the requirements.
Here I find it useful just to add some more yield statements for adding 
entries.

But now that I think again about it, it's more an example for 
generators, not so much for decorators - which I like as well.

*****

But some useful examples for decorators include

1. "Threadifying" a function, i.e. turning it into a Thread object, or 
into a callable which in turn starts a thread according to the given 
parameters.

2. Automatically calling a function if the given module is executed as a 
script, a kind of replacement for the "if __name__ == '__main__':" stuff.

3. Meta decorators:

I find it annoying to have to wrap the function given to the decorator 
into another one, modifying its properties and returning that in turn.

def wrapfunction(decorated):
     """Wrap a function taking (f, *a, **k) and replace it with a
     function taking (f) and returning a function taking (*a, **k) which
     calls our decorated function.
     """
     from functools import wraps
     @wraps(decorated)
     def wrapped_outer(f):
         @wraps(f)
         def wrapped_inner(*a, **k):
             return decorated(f, *a, **k)
         return wrapped_inner
     return wrapped_outer

makes it much easier to create decorators which just wrap a function 
into another, extending its funtionality:

@wrapfunction
def return_list(f, *a, **k)
     return list(f(*a, **k))

is much easier and IMHO much better to read than

def return_list(f):
     """Wrap a function taking (f, *a, **k) and replace it with a
     function taking (f) and returning a function taking (*a, **k) which
     calls our decorated function.
     """
     from functools import wraps
     @wraps(f)
     def wrapped(*a, **k):
         return list(f, *a, **k)
     return wrapped

- especially if used multiple times.

3a. This is a modified case of my first example: If you want a function 
to assemble and return a list instead of a generator object, but prefer 
"yield" over "ret=[]; ret.append();...", you can do that with this 
@return_list.

4. So-called "indirect decorators":

@spam(eggs)
def foo(bar):
     pass

are as well quite tricky to build when taking

def indirdeco(ind):
     from functools import update_wrapper, wraps
     upd=wraps(ind)
     # outer wrapper: replaces a call with *a, **k with an updated
     # lambda, getting the function to be wrapped and applying it and
     # *a, **k to ind.
     outerwrapper=lambda *a, **k: upd(lambda f: ind(f, *a, **k))
     # We update this as well:
     return upd(outerwrapper)
     # We don't update f nor the result of ind() - it is the callee's
     # business.

It is kind of reverse to 3.

@indirdeco
def addingdeco(f, offset):
     return lambda *a, **k: f(*a, **k) + offset
     # Here should maybe be wrapped - it is just supposed to be an
     # example.

5. Creating a __all__ for a module. Instead of maintaining it somewhere 
centrally, you can take a

class AllList(list):
     """list which can be called in order to be used as a __all__-adding
     decorator"""
     def __call__(self, obj):
         """for decorators"""
         self.append(obj.__name__)
         return obj

, do a __all__ = AllList()

and subsequently decorate each function with

@__all__

6. Re-use a generator:

A generator object is creted upon calling the generator function with 
parameters and can be used only once. A object wrapping this generator 
might be useful.

# Turn a generator into a iterable object calling the generator.
class GeneratorIterable(object):
     """Take a parameterless generator function and call it on every
     iteration."""
     def __init__(self, gen):
         # Set object attribute.
         self.gen = gen
     def __iter__(self):
         # Class attribute calls object attribute in order to keep
         # namespace variety small.
         return self.gen()


@GeneratorIterable
def mygen():
     yield 1
     yield 2

list(mygen) -> [1, 2]
list(mygen) -> [1, 2] # again, without the ()

Might be useful if the object is to be transferred to somewhere else.

*****

Some of these decorators are more useful, some less if seen standalone, 
but very handy if creating other decorators.

HTH nevertheless,


Thomas

[toc] | [prev] | [next] | [standalone]


#16928

From88888 Dihedral <dihedral88888@googlemail.com>
Date2011-12-09 10:28 -0800
Message-ID<17457040.1331.1323455329763.JavaMail.geo-discussion-forums@pret21>
In reply to#16823
On Thursday, December 8, 2011 7:43:12 PM UTC+8, Chris Angelico wrote:
> On Thu, Dec 8, 2011 at 10:22 PM, K.-Michael Aye <kmicha...@gmail.com> wrote:
> > I am still perplexed about decorators though, am happily using Python for
> > many years without them, but maybe i am missing something?
> > For example in the above case, if I want the names attached to each other
> > with a comma, why wouldn't I just create a function doing exactly this? Why
> > would I first write a single name generator and then decorate it so that I
> > never can get single names anymore (this is the case, isn't it? Once
> > decorated, I can not get the original behaviour of the function anymore.
> 
> The example given is a toy. It's hardly useful. However, there are a
> number of handy uses for decorators; mostly, they consist of giving a
> single simple keyword to a complicated set of logic. One example is
> the @classmethod and @staticmethod decorators - the code to implement
> them could be uglier than nested inline assembly, but you don't have
> to care, because you just type "@staticmethod" in front of your def
> statement and it does its magic.
> 
> Here's a handy trick that I'm sure someone has done in a more sophisticated way:
> 
> def trace(func):
>     if debugmode:
>         return lambda *a,**ka:
> (print(">"+func.__name__),func(*a,**ka),print("<"+func.__name__))[1]
>     return func
> 
> Then you put @trace in front of all your functions, and if debugmode
> is False, nothing will be done - but set it to true, and you get
> console output at the entry and exit of each function.
> 
> >>> @trace
> def test(x):
> 	print("Test! "+x)
> 	return 5
> 
> >>> test("asdf")
> >test
> Test! asdf
> <test
> 5
> 
> Again, it's helpful because it condenses all the logic (including the
> 'debugmode' flag) down to a single high level directive: "Trace this
> function".
> 
> ChrisA

I did use decorators to turn functions into iterables to be traced. 



[toc] | [prev] | [next] | [standalone]


#16936

From88888 Dihedral <dihedral88888@googlemail.com>
Date2011-12-09 16:21 -0800
Message-ID<mailman.3485.1323476480.27778.python-list@python.org>
In reply to#16928
On Saturday, December 10, 2011 2:28:49 AM UTC+8, 88888 Dihedral wrote:
> On Thursday, December 8, 2011 7:43:12 PM UTC+8, Chris Angelico wrote:
> > On Thu, Dec 8, 2011 at 10:22 PM, K.-Michael Aye <kmic...@gmail.com> wrote:
> > > I am still perplexed about decorators though, am happily using Python for
> > > many years without them, but maybe i am missing something?
> > > For example in the above case, if I want the names attached to each other
> > > with a comma, why wouldn't I just create a function doing exactly this? Why
> > > would I first write a single name generator and then decorate it so that I
> > > never can get single names anymore (this is the case, isn't it? Once
> > > decorated, I can not get the original behaviour of the function anymore.
> > 
> > The example given is a toy. It's hardly useful. However, there are a
> > number of handy uses for decorators; mostly, they consist of giving a
> > single simple keyword to a complicated set of logic. One example is
> > the @classmethod and @staticmethod decorators - the code to implement
> > them could be uglier than nested inline assembly, but you don't have
> > to care, because you just type "@staticmethod" in front of your def
> > statement and it does its magic.
> > 
> > Here's a handy trick that I'm sure someone has done in a more sophisticated way:
> > 
> > def trace(func):
> >     if debugmode:
> >         return lambda *a,**ka:
> > (print(">"+func.__name__),func(*a,**ka),print("<"+func.__name__))[1]
> >     return func
> > 
> > Then you put @trace in front of all your functions, and if debugmode
> > is False, nothing will be done - but set it to true, and you get
> > console output at the entry and exit of each function.
> > 
> > >>> @trace
> > def test(x):
> > 	print("Test! "+x)
> > 	return 5
> > 
> > >>> test("asdf")
> > >test
> > Test! asdf
> > <test
> > 5
> > 
> > Again, it's helpful because it condenses all the logic (including the
> > 'debugmode' flag) down to a single high level directive: "Trace this
> > function".
> > 
> > ChrisA
> 
> I did use decorators to turn functions into iterables to be traced.

It is easy to use decorators in python to mimic those programs in Erlang. 


[toc] | [prev] | [next] | [standalone]


#16937

From88888 Dihedral <dihedral88888@googlemail.com>
Date2011-12-09 16:21 -0800
Message-ID<6527773.1257.1323476471157.JavaMail.geo-discussion-forums@prkz16>
In reply to#16928
On Saturday, December 10, 2011 2:28:49 AM UTC+8, 88888 Dihedral wrote:
> On Thursday, December 8, 2011 7:43:12 PM UTC+8, Chris Angelico wrote:
> > On Thu, Dec 8, 2011 at 10:22 PM, K.-Michael Aye <kmic...@gmail.com> wrote:
> > > I am still perplexed about decorators though, am happily using Python for
> > > many years without them, but maybe i am missing something?
> > > For example in the above case, if I want the names attached to each other
> > > with a comma, why wouldn't I just create a function doing exactly this? Why
> > > would I first write a single name generator and then decorate it so that I
> > > never can get single names anymore (this is the case, isn't it? Once
> > > decorated, I can not get the original behaviour of the function anymore.
> > 
> > The example given is a toy. It's hardly useful. However, there are a
> > number of handy uses for decorators; mostly, they consist of giving a
> > single simple keyword to a complicated set of logic. One example is
> > the @classmethod and @staticmethod decorators - the code to implement
> > them could be uglier than nested inline assembly, but you don't have
> > to care, because you just type "@staticmethod" in front of your def
> > statement and it does its magic.
> > 
> > Here's a handy trick that I'm sure someone has done in a more sophisticated way:
> > 
> > def trace(func):
> >     if debugmode:
> >         return lambda *a,**ka:
> > (print(">"+func.__name__),func(*a,**ka),print("<"+func.__name__))[1]
> >     return func
> > 
> > Then you put @trace in front of all your functions, and if debugmode
> > is False, nothing will be done - but set it to true, and you get
> > console output at the entry and exit of each function.
> > 
> > >>> @trace
> > def test(x):
> > 	print("Test! "+x)
> > 	return 5
> > 
> > >>> test("asdf")
> > >test
> > Test! asdf
> > <test
> > 5
> > 
> > Again, it's helpful because it condenses all the logic (including the
> > 'debugmode' flag) down to a single high level directive: "Trace this
> > function".
> > 
> > ChrisA
> 
> I did use decorators to turn functions into iterables to be traced.

It is easy to use decorators in python to mimic those programs in Erlang. 


[toc] | [prev] | [next] | [standalone]


#16952

From88888 Dihedral <dihedral88888@googlemail.com>
Date2011-12-10 06:04 -0800
Message-ID<mailman.3494.1323525860.27778.python-list@python.org>
In reply to#16937
Just wrap the  exec() to spawn for fun. 

[toc] | [prev] | [next] | [standalone]


#16954

From88888 Dihedral <dihedral88888@googlemail.com>
Date2011-12-10 06:09 -0800
Message-ID<mailman.3495.1323526190.27778.python-list@python.org>
In reply to#16952
Wrap functions to yield is somewhat like  a sub-threading in Erlang.  

[toc] | [prev] | [next] | [standalone]


#17005

Fromalex23 <wuwei23@gmail.com>
Date2011-12-11 19:35 -0800
Message-ID<37dda2ec-0ff7-4df0-96a7-182656cefede@f36g2000prj.googlegroups.com>
In reply to#16954
On Dec 11, 12:09 am, 88888 Dihedral <dihedral88...@googlemail.com>
wrote:
> Wrap functions to yield is somewhat like  a sub-threading in Erlang.

Okay, now that you've replied to yourself several times, I'm convinced
you're really a markov chainer. You might want to get your owner to
tweak your response filter.

[toc] | [prev] | [next] | [standalone]


#16955

From88888 Dihedral <dihedral88888@googlemail.com>
Date2011-12-10 06:09 -0800
Message-ID<28734265.1226.1323526187915.JavaMail.geo-discussion-forums@prie17>
In reply to#16952
Wrap functions to yield is somewhat like  a sub-threading in Erlang.  

[toc] | [prev] | [next] | [standalone]


#16953

From88888 Dihedral <dihedral88888@googlemail.com>
Date2011-12-10 06:04 -0800
Message-ID<30440550.1225.1323525857598.JavaMail.geo-discussion-forums@prie17>
In reply to#16937
Just wrap the  exec() to spawn for fun. 

[toc] | [prev] | [next] | [standalone]


#16929

From88888 Dihedral <dihedral88888@googlemail.com>
Date2011-12-09 10:28 -0800
Message-ID<mailman.3483.1323455868.27778.python-list@python.org>
In reply to#16823
On Thursday, December 8, 2011 7:43:12 PM UTC+8, Chris Angelico wrote:
> On Thu, Dec 8, 2011 at 10:22 PM, K.-Michael Aye <kmicha...@gmail.com> wrote:
> > I am still perplexed about decorators though, am happily using Python for
> > many years without them, but maybe i am missing something?
> > For example in the above case, if I want the names attached to each other
> > with a comma, why wouldn't I just create a function doing exactly this? Why
> > would I first write a single name generator and then decorate it so that I
> > never can get single names anymore (this is the case, isn't it? Once
> > decorated, I can not get the original behaviour of the function anymore.
> 
> The example given is a toy. It's hardly useful. However, there are a
> number of handy uses for decorators; mostly, they consist of giving a
> single simple keyword to a complicated set of logic. One example is
> the @classmethod and @staticmethod decorators - the code to implement
> them could be uglier than nested inline assembly, but you don't have
> to care, because you just type "@staticmethod" in front of your def
> statement and it does its magic.
> 
> Here's a handy trick that I'm sure someone has done in a more sophisticated way:
> 
> def trace(func):
>     if debugmode:
>         return lambda *a,**ka:
> (print(">"+func.__name__),func(*a,**ka),print("<"+func.__name__))[1]
>     return func
> 
> Then you put @trace in front of all your functions, and if debugmode
> is False, nothing will be done - but set it to true, and you get
> console output at the entry and exit of each function.
> 
> >>> @trace
> def test(x):
> 	print("Test! "+x)
> 	return 5
> 
> >>> test("asdf")
> >test
> Test! asdf
> <test
> 5
> 
> Again, it's helpful because it condenses all the logic (including the
> 'debugmode' flag) down to a single high level directive: "Trace this
> function".
> 
> ChrisA

I did use decorators to turn functions into iterables to be traced. 



[toc] | [prev] | [next] | [standalone]


#16846

FromK.-Michael Aye <kmichael.aye@gmail.com>
Date2011-12-08 17:24 +0100
Message-ID<mailman.3428.1323361468.27778.python-list@python.org>
In reply to#16812
On 2011-12-08 11:43:12 +0000, Chris Angelico said:

> On Thu, Dec 8, 2011 at 10:22 PM, K.-Michael Aye <kmichael.aye@gmail.com> wrote:
>> I am still perplexed about decorators though, am happily using Python for
>> many years without them, but maybe i am missing something?
>> For example in the above case, if I want the names attached to each other
>> with a comma, why wouldn't I just create a function doing exactly this? Why
>> would I first write a single name generator and then decorate it so that I
>> never can get single names anymore (this is the case, isn't it? Once
>> decorated, I can not get the original behaviour of the function anymore.
> 
> The example given is a toy. It's hardly useful. However, there are a
> number of handy uses for decorators; mostly, they consist of giving a
> single simple keyword to a complicated set of logic. One example is
> the @classmethod and @staticmethod decorators - the code to implement
> them could be uglier than nested inline assembly, but you don't have
> to care, because you just type "@staticmethod" in front of your def
> statement and it does its magic.
> 
> Here's a handy trick that I'm sure someone has done in a more 
> sophisticated way:
> 
> def trace(func):
>     if debugmode:
>         return lambda *a,**ka:
> (print(">"+func.__name__),func(*a,**ka),print("<"+func.__name__))[1]
>     return func
> 
> Then you put @trace in front of all your functions, and if debugmode
> is False, nothing will be done - but set it to true, and you get
> console output at the entry and exit of each function.
> 
>>>> @trace
> def test(x):
> 	print("Test! "+x)
> 	return 5
> 
>>>> test("asdf")
>> test
> Test! asdf
> <test
> 5
> 
> Again, it's helpful because it condenses all the logic (including the
> 'debugmode' flag) down to a single high level directive: "Trace this
> function".
> 
> ChrisA

I understand this one, it seems really useful. And maybe i start to 
sense some more applicability. Like this, with extra flags that could 
be set at run time, I could influence the way a function is executed 
without designing the function too complex, but by decorating it, which 
at the end could be easier to read than complicated if-then statements 
in the function.
Thanks for your example.
Michael

[toc] | [prev] | [next] | [standalone]


#16848

FromChris Angelico <rosuav@gmail.com>
Date2011-12-09 03:38 +1100
Message-ID<mailman.3430.1323362318.27778.python-list@python.org>
In reply to#16812
On Fri, Dec 9, 2011 at 3:24 AM, K.-Michael Aye <kmichael.aye@gmail.com> wrote:
> I understand this one, it seems really useful. And maybe i start to sense
> some more applicability. Like this, with extra flags that could be set at
> run time, I could influence the way a function is executed without designing
> the function too complex, but by decorating it, which at the end could be
> easier to read than complicated if-then statements in the function.

Right, and less duplication usually results in less bugs, too.
Obviously if you go to any greater level of complexity than this you'd
want to break the lambda out into a proper function, and possibly play
with an indent level (increment on call, decrement on return). You can
also easily add the run-time check, and anything else you want to do,
too. It'll still all be buried away in the definition of trace(), and
on functions that you want to trace, you need still only have "@trace"
and nothing else.

One piece of sophistication that I would rather like to see, but don't
know how to do. Instead of *args,**kwargs, is it possible to somehow
copy in the function's actual signature? I was testing this out in
IDLE, and the fly help for the function no longer gave useful info
about its argument list.

This is why I say that this has almost certainly been done before in a
much better way.

ChrisA

[toc] | [prev] | [next] | [standalone]


#16897

Fromalex23 <wuwei23@gmail.com>
Date2011-12-08 21:02 -0800
Message-ID<0aae460e-caf1-44ce-b228-e6943fc75b7f@24g2000prd.googlegroups.com>
In reply to#16848
On Dec 9, 2:38 am, Chris Angelico <ros...@gmail.com> wrote:
> One piece of sophistication that I would rather like to see, but don't
> know how to do. Instead of *args,**kwargs, is it possible to somehow
> copy in the function's actual signature? I was testing this out in
> IDLE, and the fly help for the function no longer gave useful info
> about its argument list.

The 3rd party 'decorator' module takes care of issues like docstrings
& function signatures. I'd really like to see some of that
functionality in the stdlib though.

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.python


csiph-web