mk a écrit :
I'm trying to get print_internal_date become a static method AND to
refer to it in a class attribute 'tagdata' dict.
class PYFileInfo(FileInfo):
'python file properties'
@staticmethod
def print_internal_date(filename):
f = open(filename + 'c', "rb")
data = f.read(8)
mtime = struct.unpack("<i", data[4:])
return time.asctime(time.gmtime(mtime[0]))
tagdata = {'compiled_fname': lambda x: x + 'c',
'size': os.path.getsize,
'internal_date': print_internal_date
}
(snip)
def __get_props(self, value):
py_compile.compile(value)
for tag, fun in PYFileInfo.tagdata.items():
self[tag] = fun(value)
But:
c:/Python26/pythonw.exe -u "C:/mp3i/finfo2.py"
Traceback (most recent call last):
(snip)
File "C:/mp3i/finfo2.py", line 79, in __get_props
self[tag] = fun(value)
TypeError: 'staticmethod' object is not callable
I think I know where the problem is: what resides in tagdata is a static
method 'wrapper', not the function itself, according to:
Indeed. Sorry, I'm afraid I gave you bad advice wrt/ using a
staticmethod here - I should know better :( (well, OTHO staticmethods
are not something I use that often).
Anyway: here are a simplified version of your problem, a possible
solution that _won't_ statisfy your other constraints, 2 ugly hacks that
could work but that I don't really like, and what's possibly the "less
worse" solution if you really need a staticmethod here.
###
class Foo1(object):
""" simplified version of mk's code - test() fails """
@staticmethod
def bar(baaz):
print baaz
tagada = {'bar': bar}
def test(self, baaz):
self.tagada['bar'](baaz)
class Foo2(object):
""" naive solution : kinda work, BUT will fail
with the real code that has plain functions
in 'tagada'
"""
@staticmethod
def bar(baaz):
print baaz
tagada = {'bar': bar}
def test(self, baaz):
self.tagada['bar'].__get__(self)(baaz)
class Foo3(object):
""" working solution 1 : defer the wrapping
of 'bar' as a staticmethod
"""
def bar(baaz):
print baaz
tagada = {'bar': bar}
bar = staticmethod(bar)
def test(self, baaz):
self.tagada['bar'](baaz)
class Foo4(object):
""" working solution 2 : use a lambda """
@staticmethod
def bar(baaz):
print baaz
tagada = {'bar': lambda x : Foo4.bar(x)}
def test(self, baaz):
self.tagada['bar'](baaz)
""" and as a "less worse" solution """
def foo5bar(baaz):
print baaz
class Foo5(object):
tagada = {'bar': foo5bar}
bar = staticmethod(foo5bar)
def test(self, baaz):
self.tagada['bar'](baaz)
###
Another "solution" might be to write an alternate callable
implementation of 'staticmethod' - which I'll leave as an exercise to
the reader (...) - but that's possibly a bit overkill !-)
http://docs.python.org/reference/datamodel.html
So, how do I get out the wrapped function out of static method without
class call or instance call? (to be called in self[tag] = fun(value))
cf above. None of the solutions I could came with really statisfy me,
but well, at least 3 of them might be "good enough" depending on the
context. As far as I'm concerned, I'd first try the last one, but YMMV
Yes, I do know that if I just get rid of @staticmethod, this works
without a hitch.
But then you can't use print_internal_date as a method !-)
HTH
--
http://mail.python.org/mailman/listinfo/python-list