Don't understand this "method mapping"
Terry Reedy
tjreedy at home.com
Sat Jul 21 11:35:29 EDT 2001
"Bas Michielsen" <BMichielsen at compuserve.com> wrote in message
news:3B598059.42027565 at compuserve.com... (Cc'ed) to Bas
I am rearranging this message. First the class:
> def linear( x_in, a=0): # a=0 is a stub to get past an error
condition
> print "linear called, a =", a
> return x_in
>
> class Curve:
> map = linear
>
> def use_map( self, x):
> print "Using self.map = ", self.map
> self.y = self.map( x)
>
> def set_map( self):
> self.map = linear
> # Test code (I am running Python 1.5.2)
> ## # Output produced by the above
I am intermixing these to make things clearer
>
> c = Curve()
> print c.map
> ## <method Curve.linear of Curve instance at 80c7380>
> c.use_map( 1.0)
> ## Using self.map = <method Curve.linear of Curve instance at
80c7380>
> ## linear called, a = 1.0
> print c.y
> ## <__main__.Curve instance at 80c7380>
You apparently said print c, not c.y, which should be 1.0
> c.set_map()
> c.use_map( 1.0)
> ## Using self.map = <function linear at 80b6dd0>
> ## linear called, a = 0
> print c.y
> ## 1.0
Now the questions:
> ## I am a beginner with Python and I don't understand why in the
code below
> ## the attribute `map' first represents Curve.linear
Because you made it so, or look like so. Def always generate a
function. When you make a function an attribute of a *class*, it gets
wrapped as a method. To do so, either define the function in the
class body or assign an externally defined function: does not matter.
When you 'print' a function (or method), the definition name (stored
with the function) is used, whether or not that definition name is
currently bound to the function. Try
def f(): pass
g = f; del f
print g
and g will print as f even though there is no longer an f in the
module namespace.
Of course, since <linear> only expects one arg, calling c.map(1.0)
would generate an exception when c is added as the first argument.
> ## which also points to the external function linear
The function was defined externally, but except for *also* having a
name in the global dictionary (which you could delete after the class
definition), it it no more external than your function set_map.
Class.map is a method that wraps function <linear>. Class.set_map is
a method that wraps function <set_map>.
> ## and then, after calling set_map,
> ## is simply the external function linear for a Curve object.
set_map() assigns <linear> as a *function* attribute map of the
*instance* c, which, having the map name, will mask the class
attribute map. That is why the difference in the second use_mapp
output.
> ## I had expected that calling Curve.linear would be signalled as an
> ## attribute error because there is no method linear in class Curve
Correct. It would if you were to do so directly, by that name, but
you never did!
> ## or otherwise that the two ways to initialise the map attribute
would be
> ## equivalent???
As explained above, Curve.map and c.map are different things. They
only look alike because you called both indirectly. Try print
id(linear), id(Curve.map), id(c.map).
Terry J. Reedy
More information about the Python-list
mailing list