Init a table of functions

P

Paulo da Silva

How do I program something like the folowing program?
PYTHON claims it doesn't know about 'foo' when initializing K!
The only way I got this to work was doing the init of K in
the __init__ func. But this runs everytime for each object!
When using the name of the function without 'foo', I don't
know how to call it!

Thanks for any help.

#! /bin/env python
# -*- coding: iso-8859-15 -*-

class foo:
def f1():
print "f1"
f1=staticmethod(f1)

def f2():
print "f2"
f2=staticmethod(f2)

K={"f1" : foo.f1, \
"f1" : foo.f2 \
}


def main():
foo.K["f1"]()
foo.K["f2"]()

if __name__ == "__main__":
main()
 
R

Richard Blackwood

Paulo said:
How do I program something like the folowing program?
PYTHON claims it doesn't know about 'foo' when initializing K!
The only way I got this to work was doing the init of K in
the __init__ func. But this runs everytime for each object!
When using the name of the function without 'foo', I don't
know how to call it!

Thanks for any help.

#! /bin/env python
# -*- coding: iso-8859-15 -*-

class foo:
def f1():
print "f1"
f1=staticmethod(f1)

def f2():
print "f2"
f2=staticmethod(f2)

K={"f1" : foo.f1, \
"f1" : foo.f2 \
}


def main():
foo.K["f1"]()
foo.K["f2"]()

if __name__ == "__main__":
main()

self.f1 and self.f2 should work within any class. Try that.
 
R

Richard Blackwood

Well, I tried self and it said the same as with foo. So I just called
f1() and f2() without self or foo in front since they should be within
scope and it worked to that extent but complained further, see below:

File
"C:\Python23\Lib\site-packages\Pythonwin\pywin\framework\scriptutils.py",
line 310, in RunScript
exec codeObject in __main__.__dict__
File "..\My Documents\CODE\test_dumpscript.py", line 20, in ?
main()
File "..\My Documents\CODE\test_dumpscript.py", line 16, in main
foo.K["f1"]()
TypeError: 'staticmethod' object is not callable

How do I program something like the folowing program?
PYTHON claims it doesn't know about 'foo' when initializing K!
The only way I got this to work was doing the init of K in
the __init__ func. But this runs everytime for each object!
When using the name of the function without 'foo', I don't
know how to call it!

Thanks for any help.

#! /bin/env python
# -*- coding: iso-8859-15 -*-

class foo:
def f1():
print "f1"
f1=staticmethod(f1)

def f2():
print "f2"
f2=staticmethod(f2)

K={"f1" : foo.f1, \
"f1" : foo.f2 \
}


def main():
foo.K["f1"]()
foo.K["f2"]()

if __name__ == "__main__":
main()
 
R

Robert Kern

Paulo said:
How do I program something like the folowing program?
PYTHON claims it doesn't know about 'foo' when initializing K!
The only way I got this to work was doing the init of K in
the __init__ func. But this runs everytime for each object!
When using the name of the function without 'foo', I don't
know how to call it!

Thanks for any help.

Move the table outside of the class definition

class foo(object):
def f1():
print 'f1'
f1 = staticmethod(f1)

foo.K = {'f1': foo.f1,
}

foo.K['f1']()

--
Robert Kern
(e-mail address removed)

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter
 
R

Robert Kern

Richard Blackwood wrote:

[snip]
Now that I think of it some more, why did you add that object arg?
That's not necessary.

Habit.

--
Robert Kern
(e-mail address removed)

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter
 
R

Richard Blackwood

Robert said:
Paulo said:
How do I program something like the folowing program?
PYTHON claims it doesn't know about 'foo' when initializing K!
The only way I got this to work was doing the init of K in
the __init__ func. But this runs everytime for each object!
When using the name of the function without 'foo', I don't
know how to call it!

Thanks for any help.


Move the table outside of the class definition

class foo(object):
def f1():
print 'f1'
f1 = staticmethod(f1)

foo.K = {'f1': foo.f1,
}

foo.K['f1']()
Right Right Right.

Notice how he added the "object" as an arg to class foo.
 
R

Richard Blackwood

Move the table outside of the class definition

class foo(object):
def f1():
print 'f1'
f1 = staticmethod(f1)

foo.K = {'f1': foo.f1,
}

foo.K['f1']()
Right Right Right.
Notice how he added the "object" as an arg to class foo.

Now that I think of it some more, why did you add that object arg?
That's not necessary.
 
A

Andrew Dalke

Paulo said:
class foo:
def f1():
print "f1"
f1=staticmethod(f1) ...
K={"f1" : foo.f1, \
"f1" : foo.f2 \
}

The name 'foo' doesn't exist as a global variable
until after the class definition has been fully
executed. To make what you want work do


class foo:
def f1():
print "f1"
f1=staticmethod(f1)

def f2():
print "f2"
f2 = staticmethod(f2)

K={"f1" : f1,
"f2" : f2,
}

This works because the class definition creates
its own scope, and 'f1' and 'f2' are valid variables
in that scope.

NOTE: I removed the unneeded "\" characters for
stylistic reasons. If there's a "{" (or "(" or "[")
then the interpreter doesn't assume that a newline
means the end of the statement until after the
closing character.

The only time it's really needed is for the print
statement. In almost every other case you should
use some sort of parenthesis, brackets, etc. For
example, instead of

a = this_is_a_very_long_variable_name + \
and_here_is_another_long_name

you should use


a = (this_is_a_very_long_variable_name +
and_here_is_another_long_name)

Andrew
(e-mail address removed)
 
R

Richard Blackwood

Andrew said:
Paulo said:
class foo:
def f1():
print "f1"
f1=staticmethod(f1)
...

K={"f1" : foo.f1, \
"f1" : foo.f2 \
}


The name 'foo' doesn't exist as a global variable
until after the class definition has been fully
executed. To make what you want work do


class foo:
def f1():
print "f1"
f1=staticmethod(f1)

def f2():
print "f2"
f2 = staticmethod(f2)

K={"f1" : f1,
"f2" : f2,
}

This works because the class definition creates
its own scope, and 'f1' and 'f2' are valid variables
in that scope.

NOTE: I removed the unneeded "\" characters for
stylistic reasons. If there's a "{" (or "(" or "[")
then the interpreter doesn't assume that a newline
means the end of the statement until after the
closing character.

The only time it's really needed is for the print
statement. In almost every other case you should
use some sort of parenthesis, brackets, etc. For
example, instead of

a = this_is_a_very_long_variable_name + \
and_here_is_another_long_name

you should use


a = (this_is_a_very_long_variable_name +
and_here_is_another_long_name)

Andrew
(e-mail address removed)

Yo Andrew. That doesn't work. Check my previous post w/ errors.
 
A

Andrew Dalke

Richard said:
Yo Andrew. That doesn't work. Check my previous post w/ errors.

What do you mean?

Ahh, I see I solved the first problem (can't find 'foo')
without solving what the OP wanted. Try this reordering.

class foo:
def f1():
print "f1"

def f2():
print "f2"

K={"f1" : f1,
"f2" : f2,
}
f1 = staticmethod(f1)
f2 = staticmethod(f2)

def main():
foo.K["f1"]()
foo.K["f2"]()

if __name__ == "__main__":
main()

The 'staticmethod' is a descriptor and only works in
the context of a class.

Functions get turned into methods only in the context
of a class.

So to use a function as a function, get it before it
turns into a method or staticmethod.

Andrew
(e-mail address removed)
 
R

Richard Blackwood

class foo:
def f1():
print "f1"

def f2():
print "f2"

K={"f1" : f1,
"f2" : f2,
}
f1 = staticmethod(f1)
f2 = staticmethod(f2)

def main():
foo.K["f1"]()
foo.K["f2"]()

if __name__ == "__main__":
main()

The 'staticmethod' is a descriptor and only works in
the context of a class.

Functions get turned into methods only in the context
of a class.

So to use a function as a function, get it before it
turns into a method or staticmethod.

Andrew
(e-mail address removed)

Ingenious solution Andrew! A true beauty.
 
B

Bengt Richter

Richard said:
Yo Andrew. That doesn't work. Check my previous post w/ errors.

What do you mean?

Ahh, I see I solved the first problem (can't find 'foo')
without solving what the OP wanted. Try this reordering.

class foo:
def f1():
print "f1"

def f2():
print "f2"

K={"f1" : f1,
"f2" : f2,
}
f1 = staticmethod(f1)
f2 = staticmethod(f2)

def main():
foo.K["f1"]()
foo.K["f2"]()

if __name__ == "__main__":
main()

The 'staticmethod' is a descriptor and only works in
the context of a class.
Or where you force the issue as-if ;-)
Functions get turned into methods only in the context
of a class.
So to use a function as a function, get it before it
turns into a method or staticmethod.

Or make a custom descriptor K that invokes the getattr magic as if getting foo.f1
of foo().f1, and thus letting the staticmethod descriptor deliver the function. This
lets you generalize K to handle other kinds of class attributes as-if also.
If you wanted to exclude all but certain names allowed by K[name], you could do
that in __getitem__ by raising KeyError for the others.
This is for educational purposes only, not a general recommendation ;-)
... def f1():
... print "f1"
... f1=staticmethod(f1)
... def f2():
... print "f2"
... f2 = staticmethod(f2)
... def f3(*args):
... print 'method f3', args
... def f4(*args):
... print 'class method f4', args
... f4 = classmethod(f4)
... f5 = property(lambda *args:('property f5', args))
... class K(object):
... def __get__(self, inst, cls=None):
... if inst is None: self.obj=cls
... else: self.obj = inst
... return self
... def __getitem__(self, key):
... return getattr(self.obj, key)
... K = K()
...
>>> foo.f1
>>> foo.K['f1']
>>> foo.f1() f1
>>> foo.K['f1']() f1
>>> foo.K['f2']() f2
>>> foo.f3
>>> foo.K['f3']
>>> foo.f3(foo())
method f3 ( said:
>>> foo.K['f3'](foo())
method f3 ( said:
>>> foo.f4
>>> foo.K['f4']
>>> foo.f4()
class method f4 ( said:
>>> foo.K['f4']()
class method f4 ( said:
>>> foo.f5
>>> foo.K['f5']
<property object at 0x0090E468>

Ok, now via a foo instance:
>>> f = foo()
>>> f.f5
('property f5' said:
>>> f.K['f5']
('property f5' said:
>>> f.K['f1']
>>> f.K['f1']() f1
>>> f.f3
>>> f.f3()
method f3 ( said:
>>> f.K['f3']
>>> f.K['f3']()
method f3 (<__main__.foo object at 0x009015B0>,)

Reminder that via the class, it's unbound:
<unbound method foo.f3>

The class method is bound to the class instance either way
>>> f.K['f4']
>>> f.K['f4']()
class method f4 ( said:
>>> foo.f4
>>> foo.K['f4']
>>> foo.K['f4']()
class method f4 (<class '__main__.foo'>,)

Regards,
Bengt Richter
 
B

Bengt Richter

]
Or make a custom descriptor K that invokes the getattr magic as if getting foo.f1
of foo().f1, and thus letting the staticmethod descriptor deliver the function. This
^^-- oops, typo: that "of" should be "or" ;-/

Regards,
Bengt Richter
 
M

Michael Hoffman

Richard said:
Why a necessary good habit?

Feel free to read the web page I posted for all kinds of information
about new-style classes and why they are useful.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,209
Messages
2,571,088
Members
47,684
Latest member
sparada

Latest Threads

Top