Marco Buttu wrote: > On 11/23/2013 10:01 AM, Peter Otten wrote: > >>> In Python 3 the following two classes should be equivalent: >> Says who? >> >>> >$ 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 >>> >> >> Your script is saying that a staticmethod instance is not a callable >> object. It need not be because >> >> Foo.foo() > > Yes, you are right about Python 3. But in Python 2, if I am not going > wrong, there is not solution, and I need to define a function outside > the class. For instance: > > $ cat config.py > class Configuration(object): > > def positiveCheck(value): > if not value > 0: > raise AttributeError('Must be a positive number') > > attributes = { > # Attribute name: (type, checkrule) > 'myattr': (int, positiveCheck), > }
Just add positiveCheck = staticmethod(positiveCheck) at this point and everything should work in both Python 2 and 3. Alternatively use Steven's callable_staticmethod as a decorator. > > def __setattr__(self, name, value): > if not name in Configuration.attributes: > raise AttributeError("Attribute `%s` non allowed." %name) > > expected_type, checkrule = Configuration.attributes[name] > if not isinstance(value, expected_type): > raise TypeError('The value %s is not of type %s' \ > %(value, expected_type.__name__)) > if callable(checkrule): > print('calling %s(%s)' %(checkrule.__name__, value)) > checkrule(value) > > super(Configuration, self).__setattr__(name, value) > > The positive check works fine: > > >>> from config import Configuration > >>> c = Configuration() > >>> c.myattr = -10 > calling positiveCheck(-10) > Traceback (most recent call last): > ... > AttributeError: Must be a positive number > > But I cannot use the method as a function: > > >>> Configuration.positiveCheck(-10) > Traceback (most recent call last): > ... > Configuration instance as first argument (got int instance instead). > > Furthemore, I cannot use the method as a staticmethod, becase otherwise > it will not be callable inside the class body. PS: AttributeErrors should be raised when an attribute does not exist or cannot be set; I recommend that you raise a ValueError in positiveCheck(). -- https://mail.python.org/mailman/listinfo/python-list