Steven D'Aprano wrote:
To answer your direct question, all you need to do is manually imitate
what
Python does when you call a descriptor (see below):
py> MyClass.method_list[0].__get__(MyClass, None)()
Hello World
So, inside the foo() method, do this:
@classmethod
def foo(cls):
cls.method_list[0].__get__(cls, None)()
and it should work.
"What the hell is a descriptor?" I hear you ask. Don't worry about them,
they are an advanced part of Python, used to implement methods (regular,
class and static) and properties. If you care, you can read this:
http://docs.python.org/2/howto/descriptor.html
but you may find it heavy going. (I know I did the first five times I
read it.)
Here's another solution: use a regular function object instead of a
method. This relies on an unusual, but deliberate, quirk of the way
Python
implements methods: they are actually regular functions inside the class
body when the class is created, and don't get turned into methods
until you
do a lookup like "self.spam" or "cls.ham".
class MyClass(object):
@classmethod
def foo(cls):
# Note that you manually provide the class argument.
cls.method_list[0](cls)
def bar(cls):
print("Hello World")
# At this time, bar is still a regular function object, not a
# method of any sort.
method_list = [bar]
del bar # just to avoid any confusion
By *not* turning bar into a class method, it remains an ordinary
function object. You then store the function object inside the list,
and when you access it via method_list[0] Python gives you the regular
function, not a method. Since it is a regular function, it is callable,
but you have to manually provide the cls argument.
Thank you for this great answer!
I like the first approach (using __get__()). I tried it out but got
problem when bar operates on a class variable of MyClass:
class MyClass(object):
x = "Hello World"
@classmethod
def foo(cls):
cls.method_list[0].__get__(cls, None)()
@classmethod
def bar(cls):
print(cls.x)
method_list = [bar]
I get:
File "test.py", line 17, in bar
print(cls.x)
AttributeError: type object 'type' has no attribute 'x'
When using Peter Otten's solution bar is able to access cls.x.
_______________________________________________
Tutor maillist - Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor