472,988 Members | 2,645 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,988 software developers and data experts.

How does "delegation" work as per the FAQ?

Section 6.5 "What is delegation?" of the FAQ says:

"Python programmers can easily implement delegation. For example, the
following class implements a class that behaves like a file but converts
all written data to uppercase:

class UpperOut:
def __init__(self, outfile):
self.__outfile = outfile
def write(self, s):
self.__outfile.write(s.upper())
def __getattr__(self, name):
return getattr(self.__outfile, name)

[...] All other methods are delegated to the underlying self.__outfile
object. The delegation is accomplished via the __getattr__ method; consult
the language reference for more information about controlling attribute
access."
http://www.python.org/doc/faq/progra...-is-delegation

I don't understand how __getattr__ accomplishes delegation of other
methods. I'd expect __getattr__ to be called for attribute access, not for
method calls. And how would the arguments of a method call be passed on?

The link to the language reference doesn't help much. It says about
__getattr__: "Called when an attribute lookup has not found the attribute
in the usual places". There is no mention of method calls.

--
René Pijlman
Jul 18 '05 #1
7 3231
Rene Pijlman <re********************@my.address.is.invalid> writes:

__getattr__: "Called when an attribute lookup has not found the attribute
in the usual places". There is no mention of method calls.


A method is an attribute.

--
Ville Vainio http://www.students.tut.fi/~vainio24
Jul 18 '05 #2
Ville Vainio:
Rene Pijlman:
__getattr__: "Called when an attribute lookup has not found the attribute
in the usual places". There is no mention of method calls.


A method is an attribute.


I see. But how are the arguments of a method call passed on, when
delegation is implemented this way?

--
René Pijlman
Jul 18 '05 #3
In Python, there's little difference between
f = o.m
f(3)
and
o.m(3)
either way, the attribute 'm' is looked up on o in exactly the same
way. So the delegation pattern works no matter whether 'o.m' is a
method or is data.

Jeff

Jul 18 '05 #4
Rene Pijlman wrote:
Ville Vainio:

Rene Pijlman:

__getattr__: "Called when an attribute lookup has not found the attribute
in the usual places". There is no mention of method calls.

A method is an attribute.


I see. But how are the arguments of a method call passed on, when
delegation is implemented this way?

Jeff already gave you a fairly brief description of why this is so, but
I'll try to flesh it out somewhat. In Python, methods of objects are
actually themselves objects which wrap up an implementation function
(also an object) and a reference to the object on which they are to act
(the "self" parameter). To demonstrate this:
class x(object): .... def y( self, value ):
.... print value
.... item = x()
item <__main__.x object at 0x011EA4B0> item.y <bound method x.y of <__main__.x object at 0x011EA4B0>> x.y <unbound method x.y> item.y.im_self <__main__.x object at 0x011EA4B0> item.y.im_func <function y at 0x011E4108> item.y.__call__

<method-wrapper object at 0x00ED3B78>

So, when you do item.y( somevalue ), you are doing this set of actions:

* doing an attribute lookup in the object item for the attribute name y
o in this example, this finds the unbound method x.y in the
class, which (via various hooks (see discussions of
"descriptors")) generates a new bound method object (item.y)
for the instance "item" and returns that.
o in the sample code you found, the methods for the file
object would not be found in the instance "item"'s
dictionary or class' dictionary, so the __getattr__ hook
(which is called when an attribute lookup fails) would be
called and accomplish the delegation by doing another
attribute lookup from the object to which it is delegating
responsibility.
* calling the __call__ method of the (newly created) bound method
object with the arguments (somevalue)
o in this example, the bound method has a reference to "item"
which it will pass as the first argument to it's underlying
"y" function, so the arguments passed to the function are
(item, somevalue) (corresponding to self, somevalue in the
method signature).
o In the sample code, the bound method would have a reference
to the delegated file, rather than the delegating object, so
it will act on the underlying file.

Enjoy yourself,
Mike

_______________________________________
Mike C. Fletcher
Designer, VR Plumber, Coder
http://members.rogers.com/mcfletch/


Jul 18 '05 #5
Rene Pijlman wrote:
I don't understand how __getattr__ accomplishes delegation of other
methods. I'd expect __getattr__ to be called for attribute access, not for
method calls.
In Python a method is a callable attribute. Since a method is also an attribute, __getattr__ works equally well with instance method attributes as with instance data attributes.

This can be very confusing for programmers coming from a statically-typed background. Try to keep in mind that Python is dynamically-typed. So in the case of attributes and methods, python doesn't care what an attribute represents until the last moment, at run-time, when the program attempts to call the attribute. It is only then that Python checks to see if the attribute is callable and treats it as a method. This is real paradigm shifting material for some of us. But once you get enough examples under your belt and the gears suddenly shift, the flexibility and elegance of Python jumps out at you.
And how would the arguments of a method call be passed on?


First a quick review, by example:
class A: .... def m(self, msg): print msg a = A()
a.m <bound method A.m of <__main__.A instance at 0x4026a5ec>> a.m('hello world') hello world

When python looks-up attribute m in object a it returns the object bound to the attribute. At that point, a.m could represent any object: an integer, a list, a callable, etc.. Python will only attempt to call a.m when, at run-time, it comes across the () as in a.m('hello world'). The point here is that the look-up of the method's name is a completely separate step from calling it. The lookup (done internally by python in the above example) is done with getattr which only returns an object, it doesn't call it. So getattr is not involved with things such as function arguments or return values.

Building on the above snippet:
class B: .... a = A()
.... def __getattr__(self,name):
.... return getattr(self.a,name)
.... b=B()
b.m('hello universe')

hello universe

The statement b=B() creates an instance of class B and binds the instance object to variable b. That instance will have an attribute a which is an instance object of class A.

The statement b.m('hello universe') first causes the attribute named m to be looked-up in object b. Class B doesn't define an attribute named m, but class B does have a __getattr__ attribute (method) so python calls it. The __getattr__ method uses the getattr function to lookup what boils down to attribute m in b.a. Since b's attribute a is an instance of class A which does have an attribute named m, the getattr is satisfied. The net effect is that the expression b.m resolves to the method object b.a.m.

So after all that, back in statement b.m('hello universe'), python sees the ('hello universe') after the b.m, verifies that the result of looking-up b.m is a callable object, and calls it with the enclosed argument. The reason the __getattr__ method's code doesn't need to deal with argument lists is that the call never happens there. In the example, it happens on the command line at statement b.m('hello universe'). In that statement, the __getattr__ method's code only involvement is with determining the object for the expression b.m.

I don't know if this attempted explanation helps or just adds to the confusion. I know how obvious these concepts are once you've grasped them. But I also know how frustrating it can be until you reach that sudden "aha! moment" and you realize you've got it.

Regards,
Bill

Jul 18 '05 #6

"Rene Pijlman" <re********************@my.address.is.invalid> wrote in
message news:10********************************@4ax.com...
Ville Vainio:
Rene Pijlman:
__getattr__: "Called when an attribute lookup has not found the attribute in the usual places". There is no mention of method calls.


A method is an attribute.


I see. But how are the arguments of a method call passed on, when
delegation is implemented this way?


The delegation is done before the call, in order to find the (delegated-to
method) object on which to make the call. The alternative is to write a
wrapper method for each method delegated to and explicitly pass the args on
with *args and ** args. But doing the delegation before the call in the
method lookup make this not necessary and is much easier.

Terry J. Reedy
Jul 18 '05 #7
Terry Reedy:
The delegation is done before the call, in order to find the (delegated-to
method) object on which to make the call.


Ah, this is the missing link between my brain cells :-)

Thank you all for your kind explanation.

--
René Pijlman
Jul 18 '05 #8

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

Similar topics

10
by: Scott Brady Drummonds | last post by:
Hi, everyone, I'm still learning Python as I develop a medium-sized project. From my previous experience with C++, I've burnt into my mind the notion of information hiding. I'm having trouble...
7
by: KJ | last post by:
What does this do: <xsl:apply-templates select="." /> ?
3
by: Arthur Connor | last post by:
Currently I specified a TARGET attribute inside an <A> tag which is not allowed under strict XHTML. How do I change the line to meet the requirements of strict HTML? <A...
3
by: Tony Johansson | last post by:
Hello! What does it mean with delegation and can you give me one example. //Tony
6
by: Marc Castrechini | last post by:
This is a classic double hop delegation issue, however its the first time we are setting this up so we are doing something incorrectly. If we run through the IDE or using a localhost path on the...
3
by: Patrick | last post by:
Hello I have the following scenario - SQL 2005 server (serversql) - Windows 2003 with IIS (serveriis) - Windows 2003 ADS (serverads) I want to connect to an intranet application using NTML...
3
by: SkyZhao | last post by:
i use attachEvent to bind a event ; code: img.attachEvent("onclick",alert("aa")); div.appendChild(img); div.innerHTML+="some text"; the event can not work; why can't i use it? if i use...
2
by: Wimpie van Lingen | last post by:
Hey I have some more questions with regards to Remoting in .NET 2. I'm using TCP with the Binary formatter. My solution consists of 4 projects: - Class Library containing the server classes...
19
by: maya | last post by:
hi, so what is "modern" javascript?? the same as "DOM-scripting"? i.e., editing content (or changing appearance of content) dynamically by massaging javascript objects, html elements, etc? ...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
2
by: giovanniandrean | last post by:
The energy model is structured as follows and uses excel sheets to give input data: 1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
0
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
4
by: GKJR | last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...
3
SueHopson
by: SueHopson | last post by:
Hi All, I'm trying to create a single code (run off a button that calls the Private Sub) for our parts list report that will allow the user to filter by either/both PartVendor and PartType. On...

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.