From: lallous on
Hello,

Learning Python from the help file and online resources can leave one
with many gaps. Can someone comment on the following:

# ---------
class X:
T = 1

def f1(self, arg):
print "f1, arg=%d" % arg
def f2(self, arg):
print "f2, arg=%d" % arg
def f3(self, arg):
print "f3, arg=%d" % arg

# this:
F = f2
# versus this:
func_tbl = { 1: f1, 2: f2, 3: f3 }

def test1(self, n, arg):
# why passing 'self' is needed?
return self.func_tbl[n](self, arg)

def test2(self):
f = self.f1
f(6)

f = self.F
# why passing self is not needed?
f(87)

# ---------
x = X()

x.test1(1, 5)
print '----------'
x.test2()

Why in test1() when it uses the class variable func_tbl we still need
to pass self, but in test2() we don't ?

What is the difference between the reference in 'F' and 'func_tbl' ?

Thanks,
Elias
From: TomF on
On 2010-03-15 09:39:50 -0700, lallous <elias.bachaalany(a)gmail.com> said:

> Hello,
>
> Learning Python from the help file and online resources can leave one
> with many gaps. Can someone comment on the following:
>
> # ---------
> class X:
> T = 1
>
> def f1(self, arg):
> print "f1, arg=%d" % arg
> def f2(self, arg):
> print "f2, arg=%d" % arg
> def f3(self, arg):
> print "f3, arg=%d" % arg
>
> # this:
> F = f2
> # versus this:
> func_tbl = { 1: f1, 2: f2, 3: f3 }
>
> def test1(self, n, arg):
> # why passing 'self' is needed?
> return self.func_tbl[n](self, arg)
>
> def test2(self):
> f = self.f1
> f(6)
>
> f = self.F
> # why passing self is not needed?
> f(87)
>
> # ---------
> x = X()
>
> x.test1(1, 5)
> print '----------'
> x.test2()
>
> Why in test1() when it uses the class variable func_tbl we still need
> to pass self, but in test2() we don't ?
>
> What is the difference between the reference in 'F' and 'func_tbl' ?

I recommend putting print statements into your code like this:

def test1(self, n, arg):
print "In test1, I'm calling a %s" % self.func_tbl[n]
return self.func_tbl[n](self, arg)

def test2(self):
f = self.f1
print "Now in test2, I'm calling a %s" % f
f(6)


Bottom line: You're calling different things. Your func_tbl is a dict
of functions, not methods.

-Tom

From: Rami Chowdhury on
On Monday 15 March 2010 10:42:41 TomF wrote:
> On 2010-03-15 09:39:50 -0700, lallous <elias.bachaalany(a)gmail.com> said:
> >
> > Why in test1() when it uses the class variable func_tbl we still need
> > to pass self, but in test2() we don't ?
> >
> > What is the difference between the reference in 'F' and 'func_tbl' ?
>
> I recommend putting print statements into your code like this:
>
> def test1(self, n, arg):
> print "In test1, I'm calling a %s" % self.func_tbl[n]
> return self.func_tbl[n](self, arg)
>
> def test2(self):
> f = self.f1
> print "Now in test2, I'm calling a %s" % f
> f(6)
>
>
> Bottom line: You're calling different things. Your func_tbl is a dict
> of functions, not methods.
>
> -Tom

To build on that a bit, note that in test2() you are doing:
> > f = self.f1
> > f(6)
> >
> > f = self.F
> > # why passing self is not needed?
> > f(87)

As I understand it, since you obtained the reference to 'f1' from 'self', you
got it as a bound rather than an unbound method. So 'self' is automatically
passed in as the first argument.

----
Rami Chowdhury
"Given enough eyeballs, all bugs are shallow." -- Linus' Law
408-597-7068 (US) / 07875-841-046 (UK) / 01819-245544 (BD)
From: Bruno Desthuilliers on
lallous a �crit :
> Hello,
>
> Learning Python from the help file and online resources can leave one
> with many gaps. Can someone comment on the following:

(snip code)

> Why in test1() when it uses the class variable func_tbl we still need
> to pass self, but in test2() we don't ?
>
> What is the difference between the reference in 'F' and 'func_tbl' ?

Answer here:

http://wiki.python.org/moin/FromFunctionToMethod

From: Jason Tackaberry on
On Tue, 2010-03-16 at 10:04 +0100, Bruno Desthuilliers wrote:
> Answer here:
>
> http://wiki.python.org/moin/FromFunctionToMethod

I have a sense I used to know this once upon a time, but the question
came to my mind (possibly again) and I couldn't think of an answer:

Why not create the bound methods at instantiation time, rather than
using the descriptor protocol which has the overhead of creating a new
bound method each time the method attribute is accessed?

Cheers,
Jason.