Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #28921 > unrolled thread
| Started by | j.m.dagenhart@gmail.com |
|---|---|
| First post | 2012-09-11 19:28 -0700 |
| Last post | 2012-09-12 04:15 -0700 |
| Articles | 8 — 7 participants |
Back to article view | Back to comp.lang.python
generators as decorators simple issue j.m.dagenhart@gmail.com - 2012-09-11 19:28 -0700
Re: generators as decorators simple issue Ramchandra Apte <maniandram01@gmail.com> - 2012-09-11 19:55 -0700
Re: generators as decorators simple issue alex23 <wuwei23@gmail.com> - 2012-09-11 21:39 -0700
Re: generators as decorators simple issue Thomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de> - 2012-09-12 08:08 +0200
Re: generators as decorators simple issue pyjoshsys <j.m.dagenhart@gmail.com> - 2012-09-12 03:22 -0700
Re: generators as decorators simple issue Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2012-09-12 11:47 +0100
Re: generators as decorators simple issue Ian Kelly <ian.g.kelly@gmail.com> - 2012-09-12 09:09 -0600
Re: generators as decorators simple issue pyjoshsys <j.m.dagenhart@gmail.com> - 2012-09-12 04:15 -0700
| From | j.m.dagenhart@gmail.com |
|---|---|
| Date | 2012-09-11 19:28 -0700 |
| Subject | generators as decorators simple issue |
| Message-ID | <e738542a-f864-4ad0-9aaa-738047356841@googlegroups.com> |
I'm trying to call SetName on an object to prevent me from ever having to call it explictly again on that object. Best explained by example.
def setname(cls):
'''this is the proposed generator to call SetName on the object'''
try:
cls.SetName(cls.__name__)
finally:
yield cls
class Trial:
'''class to demonstrate with'''
def SetName(self, name):
print 1, 1
@setname
class Test(Trial):
'''i want SetName to be called by using setname as a decorator'''
def __init__(self):
print 'Yay! or Invalid.'
if __name__ == '__main__':
test = Test()
How can i fix this?
This is my exact error: python decors2.py
Traceback (most recent call last):
File "decors2.py", line 23, in <module>
test = Test()
TypeError: 'generator' object is not callable
[toc] | [next] | [standalone]
| From | Ramchandra Apte <maniandram01@gmail.com> |
|---|---|
| Date | 2012-09-11 19:55 -0700 |
| Message-ID | <9ead5a5c-2fe0-44ce-9d90-13e19b95d31e@googlegroups.com> |
| In reply to | #28921 |
On Wednesday, 12 September 2012 07:58:10 UTC+5:30, pyjoshsys wrote: > I'm trying to call SetName on an object to prevent me from ever having to call it explictly again on that object. Best explained by example. > [snip] In your decorator, you are using `yield cls` - it should be `return cls` 99.99% of the time.
[toc] | [prev] | [next] | [standalone]
| From | alex23 <wuwei23@gmail.com> |
|---|---|
| Date | 2012-09-11 21:39 -0700 |
| Message-ID | <14d034e0-d477-4cde-8a7c-1f31f2e68ee2@v19g2000pbt.googlegroups.com> |
| In reply to | #28921 |
On Sep 12, 12:28 pm, j.m.dagenh...@gmail.com wrote: > def setname(cls): > '''this is the proposed generator to call SetName on the object''' > try: > cls.SetName(cls.__name__) > finally: > yield cls A generator is (basically) a callable that acts like an iterator. You'd use a generator if you wanted to loop with for or a list comprehension across the output of the generator: for foo in setname(Test) A decorator is a callable that takes another callable as an argument, either modifying it or returning a wrapped version of it: Test = setname(Test) You don't want to iterate over anything, so you should change `yield` to `return`.
[toc] | [prev] | [next] | [standalone]
| From | Thomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de> |
|---|---|
| Date | 2012-09-12 08:08 +0200 |
| Message-ID | <k2p8s7$jlc$1@r03.glglgl.gl> |
| In reply to | #28921 |
Am 12.09.2012 04:28 schrieb j.m.dagenhart@gmail.com:
> I'm trying to call SetName on an object to prevent me from ever having to call it explictly again on that object. Best explained by example.
>
>
> def setname(cls):
> '''this is the proposed generator to call SetName on the object'''
> try:
> cls.SetName(cls.__name__)
> finally:
> yield cls
>
>
> class Trial:
> '''class to demonstrate with'''
> def SetName(self, name):
> print 1, 1
>
> @setname
> class Test(Trial):
> '''i want SetName to be called by using setname as a decorator'''
> def __init__(self):
>
> print 'Yay! or Invalid.'
>
> if __name__ == '__main__':
> test = Test()
>
>
> How can i fix this?
I am not sure what exactly you want to achieve, but I see 2 problems here:
1. Your setname operates on a class, but your SetName() is an instance
function.
2. I don't really understand the try...finally yield stuff. As others
already said, you probably just want to return. I don't see what a
generator would be useful for here...
def setname(cls):
'''this is the proposed generator to call SetName on the object'''
try:
cls.SetName(cls.__name__)
finally:
return cls
and
class Trial(object):
'''class to demonstrate with'''
@classmethod
def SetName(cls, name):
print 1, 1
should solve your problems.
[toc] | [prev] | [next] | [standalone]
| From | pyjoshsys <j.m.dagenhart@gmail.com> |
|---|---|
| Date | 2012-09-12 03:22 -0700 |
| Message-ID | <3ffa457e-7836-46d0-8246-03b6bd90a025@googlegroups.com> |
| In reply to | #28921 |
The output is still not what I want. Now runtime error free, however the output is not what I desire.
def setname(cls):
'''this is the proposed generator to call SetName on the object'''
try:
cls.SetName(cls.__name__)
except Exception as e:
print e
finally:
return cls
class Trial(object):
'''class to demonstrate with'''
def __init__(self):
object.__init__(self)
self.name = None
@classmethod
def SetName(cls, name):
cls.name = name
@setname
class Test(Trial):
'''i want SetName to be called by using setname as a decorator'''
def __init__(self):
Trial.__init__(self)
if __name__ == '__main__':
test = Test()
print 'instance'
print '', test.name #should be Test
print 'class'
print '', Test.name
The output is: python decors2.py
instance
None
class
Test
I want:
instance
Test
class
Test
Is this possible in this manner?
[toc] | [prev] | [next] | [standalone]
| From | Oscar Benjamin <oscar.j.benjamin@gmail.com> |
|---|---|
| Date | 2012-09-12 11:47 +0100 |
| Message-ID | <mailman.547.1347446843.27098.python-list@python.org> |
| In reply to | #28942 |
On Wed, 12 Sep 2012 03:22:31 -0700 (PDT), pyjoshsys <j.m.dagenhart@gmail.com> wrote: > The output is still not what I want. Now runtime error free, however the output is not what I desire. > def setname(cls): > '''this is the proposed generator to call SetName on the object''' > try: > cls.SetName(cls.__name__) > except Exception as e: > print e > finally: > return cls I would write the function above in one line: cls.name = name > class Trial(object): > '''class to demonstrate with''' > def __init__(self): > object.__init__(self) > self.name = None Remove the line above. The instance attribute self.name is hiding the class attribute cls.name. Oscar
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2012-09-12 09:09 -0600 |
| Message-ID | <mailman.566.1347462581.27098.python-list@python.org> |
| In reply to | #28942 |
On Wed, Sep 12, 2012 at 4:22 AM, pyjoshsys <j.m.dagenhart@gmail.com> wrote: > The output is still not what I want. Now runtime error free, however the output is not what I desire. [SNIP] > class Trial(object): > '''class to demonstrate with''' > def __init__(self): > object.__init__(self) > self.name = None > > @classmethod > def SetName(cls, name): > cls.name = name [SNIP] > if __name__ == '__main__': > test = Test() > print 'instance' > print '', test.name #should be Test > print 'class' > print '', Test.name > > > The output is: python decors2.py > instance > None > class > Test > > I want: > instance > Test > class > Test > > Is this possible in this manner? The SetName class method sets the name on the *class* dictionary. The class's __init__ method also sets a name (None) on the *instance* dictionary. From an instance's perspective, the instance dictionary will shadow the class dictionary. If you remove the attribute from the instance dictionary entirely (delete the "self.name = None" line), and leave the class dictionary as is, then you will get the output you want (although from your later post I am not certain that this is the behaviour you want). On Wed, Sep 12, 2012 at 5:15 AM, pyjoshsys <j.m.dagenhart@gmail.com> wrote: > so decorators only pass the object and not any instance of the object as the implied argument? Is this right? Right. > The idea was to use @setname instead of instance.SetName(instance.__name__). The appropriate place to do this so that it applies to all instances of the class rather than to the class would be inside the __init__ method. Also, instances don't have a __name__ attribute, so it's still unclear to me what you're looking for. Did you mean the effect to be that of "instance.SetName(cls.__name__)"? If so, then the decorator approach (with the line "self.name = None" removed) should be fine for your purposes -- you'll just have the name stored in the class dict instead of in each instance dict, but it will still be visible as long as you haven't shadowed it.
[toc] | [prev] | [next] | [standalone]
| From | pyjoshsys <j.m.dagenhart@gmail.com> |
|---|---|
| Date | 2012-09-12 04:15 -0700 |
| Message-ID | <eb154bbe-8836-431f-831e-8763544b1c54@googlegroups.com> |
| In reply to | #28921 |
so decorators only pass the object and not any instance of the object as the implied argument? Is this right? The idea was to use @setname instead of instance.SetName(instance.__name__). I thought decorators would do this, but it seems not.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web