Welcome, guest | Sign In | My Account | Store | Cart

I was looking for a way to have a method that when called on a class would get the class as its first argument, and when called on an instance would get that instance. Here is a nice way to do this (curry implementation thanks to http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/222061)

Python, 29 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# from recipe 222061
curry = lambda func, *args, **kw:\
            lambda *p, **n:\
                func(*args + p, **dict(kw.items() + n.items()))

# bothmethod as a descriptor/decorator
class bothmethod(object):
    def __init__(self, func):
        self.func = func

    def __get__(self, obj, type=None):
        if obj is None:
            return curry(self.func, type)
        else:
            return curry(self.func, obj)

# test
class Test(object):
    @bothmethod
    def method(self_or_cls):
        print 'The first argument is: %s' % self_or_cls

# when called on the class, it gets the class
>>> Test.method()
The first argument is: <class '__main__.Test'>

# when called on an instance, it gets that instance
>>> Test().method()
The first argument is: <__main__.Test object at 0xb7d5ad0c>

Another way to do this would be to have a __hidden_method, have public_method = classmethod(__hidden_method) in the class, and set public_method = __hidden_method in __init__. This solution isn't very clean though, while this decorator is reusable :-)

Created by Samuel Cormier-Iijima on Sun, 8 Jul 2007 (PSF)
Python recipes (4591)
Samuel Cormier-Iijima's recipes (1)

Required Modules

  • (none specified)

Other Information and Tasks