On Sat, 23 Nov 2013 09:28:43 +0100, Marco Buttu wrote: > In Python 3 the following two classes should be equivalent:
They certainly are not equivalent in *any* version of Python, because staticmethods are not equivalent to instance methods. > $ cat foo.py > class Foo: > def foo(): > pass > print(callable(foo)) > > class Foo: > @staticmethod > def foo(): > pass > print(callable(foo)) > > But they do not: > > $ python3 foo.py > True > False And Python 2 gives the same result for staticmethods: [steve@ando ~]$ python2.7 Python 2.7.2 (default, May 18 2012, 18:25:10) [GCC 4.1.2 20080704 (Red Hat 4.1.2-52)] on linux2 Type "help", "copyright", "credits" or "license" for more information. py> py> class Test(object): ... @staticmethod ... def method(): ... pass ... print callable(method) ... False > How come the metaclass does not skip the staticmethod decorator? What makes you think the metaclass gets the opportunity to skip the decorator? By the time the metaclass gets called, the decorator has already run. You seem to be conflating behaviour in Python 2 that doesn't actually occur. Staticmethods are not directly callable in any version of Python. The problem you seem to have is that you want to call a method both during and after construction: class MyClass(object): def helper(arg): return arg + 1 x = helper(10) y = helper(20) def method(self, arg): return self.helper(arg) Here, the attributes x and y rely on calling helper as a function, where it does not receive a self argument, but when calling helper from inside the instance method, or when calling it like MyClass.helper(), it will receive a self argument. Unfortunately there is no good solution to this using just built-ins. staticmethod doesn't work, as it's not callable. However, we can create our own callable version of staticmethod: class callable_staticmethod(object): def __init__(self, func): self.func = func def __get__(self, obj, cls=None): return self.func def __call__(self, *args, **kwargs): return self.func(*args, **kwargs) class MyClass(object): @callable_staticmethod def helper(arg): return arg + 1 x = helper(10) y = helper(20) def method(self, arg): return self.helper(arg) This should now work exactly as you hope. -- Steven -- https://mail.python.org/mailman/listinfo/python-list