473,698 Members | 2,181 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

super, decorators and gettattribute

Hello all,

I am playing around w/ Python's object system and decorators and I
decided to write (as an exercise) a decorator that (if applied to a
method) would call the superclass' method of the same name before
doing anything (initially I wanted to do something like CLOS
[1] :before and :end methods, but that turned out to be too
difficult).

However, I cannot get it right (specially, get rid of the eval). I
suspect that I may be misunderstandin g something happening between
super objects and __getattribute_ _ methods.

Here's my code:

def endmethod(fun):
"""Decorato r to call a superclass' fun first.

If the classes child and parent are defined as below, it should
work like:
>>x = child()
x.foo()
I am parent's foo
I am child's foo.
"""
name = fun.__name__
def decorated(self, *args, **kwargs):
try:
super_object = super(self.__cl ass__, self)

# now I want to achieve something equivalent to calling
# parent.foo(*arg s, **kwargs)
# if I wanted to limit it only to this example

# this doesn't work: in the example, it calls child's foo,
# entering in an eternal loop (instead of calling parent's
# foo, as I would expect).

# super_object.__ getattribute__( name)(*args, **kwargs)

# this does work, but I feel it's ugly
eval('super_obj ect.%s(*args, **kwargs)' % name)
except AttributeError:
pass # if parent doesn't implement fun, we don't care
# about it
return fun(self, *args, **kwargs) # hopefully none

decorated.__nam e__ = name
return decorated
class parent(object):
def foo(self):
print 'I am parent\'s foo'

class child(parent):
@endmethod
def foo(self):
print "I am foo\'s foo."

if __name__=='__ma in__':
x = child()
x.foo()

Can anybody tell me how to call a superclass method knowing its name?

Thanks in advance,
-- Richard

[1] http://en.wikipedia.org/wiki/Common_Lisp_Object_System
Jan 12 '08
18 2496
On Jan 12, 6:56 pm, Steven D'Aprano <st...@REMOVE-THIS-
cybersource.com .auwrote:
On Sat, 12 Jan 2008 15:47:05 -0500, Mike Meyer wrote:
There's an apparently common bug here: you don't want to pass super
self.__class__, but the class that the method is bound to.

Given an instance method, is it possible to easily determine what class
it is defined in?

I thought the im_class attribute might do it, but it apparently just
points to self.__class__.
>class Foo(object):

... def foo(self):
... pass
...>>class Bar(Foo):

... def bar(self):
... pass
...>>Bar().bar. im_class # expecting Bar

<class '__main__.Bar'> >>Bar().foo.im_ class # hoping for Foo

<class '__main__.Bar'>
Something like that seems to work for most cases:

from inspect import getmro

def getdef(obj,attr ):
try: objattrs = obj.__dict__
except AttributeError:
objattrs = obj.__slots__
if attr in objattrs:
return obj
for cls in getmro(obj.__cl ass__):
if attr in cls.__dict__:
return cls
>>getdef(Bar( ), 'bar')
<class '__main__.Bar'>
>>getdef(Bar( ), 'foo')
<class '__main__.Foo'>
It probably misses some edge cases but I can't think of any off the
top of my head.

George
Jan 14 '08 #11
On Jan 14, 1:41 pm, Richard Szopa <ryszard.sz...@ gmail.comwrote:
On Jan 13, 3:31 pm, thebjorn <BjornSteinarFj eldPetter...@gm ail.com>
wrote:
They do, except for when it comes to what super(..) returns. It isn't
really an object in the sense that they're presented in the tutorial,
but rather a sort of proxy to the methods in the ancestor classes of
the concrete object (self), relative to the current method's class. I
can't imagine that sentence would ease any confusion however, suffice
it to say that you have to call getattr(super(. .), 'name') instead of
super(..).__get attr__('name') and you have to call super(..).__len __()
instead of len(super(..)) -- I can't imagine that lessens any
confusion either :-/

Surprisingly, I think your first sentence *does* make something more
clear. Let me check if I understand it right: when we call a method on
super(Foo, self) it is as if we were calling call-next-method in
Common Lisp or Dylan
I don't remember if CLOS was changed to use C3 Linearization also, but
the concept came from Dylan (http://www.webcom.com/haahr/dylan/
linearization-oopsla96.html) and that's what is implemented in Python.

[...]
However, there's one piece that doesn't completely fit to the puzzle:
why does getattr work? The help says:

getattr(...)
getattr(object, name[, default]) -value

Get a named attribute from an object; getattr(x, 'y') is
equivalent to x.y. When a default argument is given, it
is returned when the attribute doesn't exist; without it,
an exception is raised in that case.

Does it work on the basis that "getattr(x, 'y') is equivalent to x.y"?
What is then a "named attribute for an object" in Python? It seems not
to be equivalent to the value of the item whose name is 'y' in the
object's class __dict__...
Conceptually, x.y is always "get the y attribute of x" and the same as
getattr(x, 'y'). Depending on the type of x and y, and your
familiarity with Python internals, what actually happens during a
lookup might be surprising. In the vast majority of cases however, x.y
is equivalent to one of

x.__dict__['y']
type(x).__dict_ _['y']

but if you're a language geek like me, you might be excited that in
some cases it is

type(x).__dict_ _['y'].__get__(x, type(x))

which says you get the value of x.y by calling y and passing x as an
argument -- if you know CLOS you'll recognize that it's a primitive
multi-method call. (there are some other special cases too, although
not as exciting ;-)

Much more detail can be found in Raymond's paper on descriptors
(http://users.rcn.com/python/download/Descriptor.htm) and Michele's
paper on super (http://www.phyast.pitt.edu/~micheles/python/
super.html).

-- bjorn
Jan 14 '08 #12
Michele Simionato <mi************ ***@gmail.comwr ites:
I really need to publish this one day or another, since these
questions about super keeps coming out:

http://www.phyast.pitt.edu/~micheles/python/super.html
Yes, please. Your article has improved my understanding just from
skimming the main headings :-)

--
\ "Buy not what you want, but what you need; what you do not need |
`\ is expensive at a penny." -- Cato, 234-149 BC, Relique |
_o__) |
Ben Finney
Jan 14 '08 #13
On Jan 14, 11:05 pm, thebjorn <BjornSteinarFj eldPetter...@gm ail.com>
wrote:
I don't remember if CLOS was changed to use C3 Linearization also, but
the concept came from Dylan (http://www.webcom.com/haahr/dylan/
linearization-oopsla96.html) and that's what is implemented in Python.
The Common Lisp ANSI standard is from 1994, and the article you cite
is from 1996, which strongly suggests C3 linearization wasn't included
in CLOS. The most important difference between CLOS and C3
linearization AFAIK is that the latter enforces monotonicity, while
the former doesn't.

Of course, it shouldn't be very difficult to implement the C3 behavior
in Common Lisp using the de facto standard MetaObject Protocol.

(Nb. Dylan was such a nice language... It's a pity it is practically
dead right now.)
but if you're a language geek like me, you might be excited that in
some cases it is

type(x).__dict_ _['y'].__get__(x, type(x))

which says you get the value of x.y by calling y and passing x as an
argument -- if you know CLOS you'll recognize that it's a primitive
multi-method call. (there are some other special cases too, although
not as exciting ;-)
Yeah, I also feel the excitement, so probably I am a language geek
too ;-). However, this is still quite far away from full fledged
multimethods. (OTOH trying to get something more from these primitive
multimethods by abusing __get__ looks kind of tempting ;-))

Regards,

-- Richard
Jan 14 '08 #14
On Jan 14, 7:53 am, Michele Simionato <michele.simion ...@gmail.com>
wrote:
I really need to publish this one day or another, since these
questions
about super keeps coming out:

http://www.phyast.pitt.edu/~micheles/python/super.html
Please do. It is a very enlightening discussion, and I'm sure a bunch
of folks will benefit from it. And please update it (if necessary) to
the current Python version. At the time of that writing, 2.3 must have
been King, but oh my, how time flies :-)

Cheers,
-Basilisk96
Jan 15 '08 #15
On Jan 14, 11:47 pm, Richard Szopa <ryszard.sz...@ gmail.comwrote:
Could you tell me what are the pros and cons of the two approaches
(i.e. writing a decorator function and a decorator descriptor class)?
I prefer to use a class for introspection sake, since
there is no way to get information about an inner function
in a closure, whereas your users can introspect classes
pretty well.
super_object = super(self.__cl ass__, self)
Notice that using super(self.__cl ass__, self) is a common
mistake: the pitfalls with inheritance were discussed
very recently in this same newsgroup, you should be
able to find the post. What you need is

super(class_whe re_the_method_i s_defined, self)

which is in general different from

super(self.__cl ass__, self)

There is no clean way to determine the current class
in Python < 3.0 (Python 3.0 does it automatically);
if you want to see a hackish way involving
bytecode tricks see
http://groups.google.com/group/comp....a2da68961caeb6

(and notice that this is really not recommended).

Michele Simionato
Jan 15 '08 #16
On Jan 13, 5:51 am, Richard Szopa <ryszard.sz...@ gmail.comwrote:
On Jan 13, 8:59 am, Marc 'BlackJack' Rintsch <bj_...@gmx.net wrote:
On Sat, 12 Jan 2008 14:23:52 -0800, Richard Szopa wrote:
However, I am very surprised to learn that
super_object.__ getattr__(name) (*args, **kwargs)
getattr(super_o bject, name)(*args, **kwargs)
are not equivalent. This is quite odd, at least when with len()
and .__len__, str() and .__str__. Do you maybe know what's the
rationale behind not following that convention by getattr?
I think you are confusing `__getattr__` and `__getattribute __` here!
`getattr()` maps to `__getattr__()` , it's `__getattribute __` that's
different.

Well, in my code calling super_object.__ getattr__(name) (*args,
**kwargs) and getattr(super_o bject, name)(*args, **kwargs) gives
*different* effects (namely, the latter works, while the former
doesn't). That kinda suggests that they don't map to each other :-).
And that makes me feel confused.
Don't think of them as mappings. Think of them as a way for a class
to hook into getattr's protocol, conveniently named similar to getattr
(__getattr__ and __getattribute_ _). getattr() may call several
methods, no methods at all, change the arguments, etc. Although len()
may seem simple, many others are not so simple.

--
Adam Olsen, aka Rhamphoryncus
Jan 15 '08 #17
Michele Simionato wrote:
I really need to publish this one day or another, since these
questions
about super keeps coming out:

http://www.phyast.pitt.edu/~micheles/python/super.html
Unfortunately the links [2], [3] and [4] are not given,

Helmut.
--
Helmut Jarausch

Lehrstuhl fuer Numerische Mathematik
RWTH - Aachen University
D 52056 Aachen, Germany
Jan 15 '08 #18
On Jan 15, 8:06 pm, Helmut Jarausch <jarau...@skyne t.bewrote:
Unfortunately the links [2], [3] and [4] are not given,
Luckily, there's Google :)

[2] Article about MRO: http://www.python.org/download/releases/2.3/mro/
[3] Descriptor HowTo: http://users.rcn.com/python/download/Descriptor.htm
[4] Articles about metaclasses (second one relevant to super):
* http://www.ibm.com/developerworks/li.../l-pymeta.html,
* http://www-128.ibm.com/developerwork...GX03&S_CMP=ART,
* http://www.ibm.com/developerworks/li...GX03&S_CMP=ART

Of course, it would be very nice if the article was updated to include
the links.

HTH,

-- Richard

Jan 15 '08 #19

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

Similar topics

4
2064
by: Michael Sparks | last post by:
Anyway... At Europython Guido discussed with everyone the outstanding issue with decorators and there was a clear majority in favour of having them, which was good. From where I was sitting it looked like about 20:20 split on the following syntaxes: 1 def func(arg1, arg2, arg3) : function... 2 def func(arg1, arg2, arg3): function...
17
1772
by: daishi | last post by:
For what it's worth: As far as I know, the proposed @decorator syntax will be the first time that two logical lines of python with the same indentation will not be independent of one another. Previously, when looking at: some_python(code) and_some_more = stuff there was no need to look at the the first line in order to know what
4
1483
by: RebelGeekz | last post by:
Just my humble opinion: def bar(low,high): meta: accepts(int,int) returns(float) #more code Use a metadata section, no need to introduce new messy symbols, or mangling our beloved visual cleanliness of python.
2
1704
by: Guido van Rossum | last post by:
Robert and Python-dev, I've read the J2 proposal up and down several times, pondered all the issues, and slept on it for a night, and I still don't like it enough to accept it. The only reason to accept it would be to pacify the supporters of the proposal, and that just isn't a good enough reason in language design. However, it got pretty darn close! I'm impressed with how the community managed to pull together and face the enormous...
0
2346
by: Anthony Baxter | last post by:
To go along with the 2.4a3 release, here's an updated version of the decorator PEP. It describes the state of decorators as they are in 2.4a3. PEP: 318 Title: Decorators for Functions and Methods Version: $Revision: 1.34 $ Last-Modified: $Date: 2004/09/03 09:32:50 $ Author: Kevin D. Smith, Jim Jewett, Skip Montanaro, Anthony Baxter
9
1708
by: Paul Rubin | last post by:
I'm trying the super() function as described in Python Cookbook, 1st ed, p. 172 (Recipe 5.4). class A(object): def f(self): print 'A' class B(object): def f(self):
11
2095
by: Helmut Jarausch | last post by:
Hi, are decorators more than just syntactic sugar in python 2.x and what about python 3k ? How can I find out the predefined decorators? Many thanks for your help, Helmut Jarausch
2
1949
by: Andrew West | last post by:
Probably a bit of weird question. I realise decorators shouldn't be executed until the function they are defined with are called, but is there anyway for me to find all the decorates declared in a file when I import it? Or perhaps anyway to find the decorators by loading the file by other methods (with out simply parsing it by hand). Basically what I'm looking for is a way to, given a python file, look through that file and find all the...
12
344
by: iu2 | last post by:
Hi I'm trying to make a method call automatically to its super using this syntax: class A: chained = def pr(self): print 'Hello from A'
0
9016
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8887
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8856
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7709
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6515
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5858
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 then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4613
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
2321
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
1997
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 can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.