Static method
Bruno Desthuilliers
bruno.42.desthuilliers at websiteburo.invalid
Thu Feb 18 06:54:44 EST 2010
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
More information about the Python-list
mailing list