ActiveState Code

Recipe 113645: Classmethod emulation in python2.1


Class methods were introduced in python2.2. The following code illistrates how the same effect can be achived in python 2.1 and probably under although I haven't checked.

Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# junk.py

def classmethod(method):
    '''Impulate py2.2 classmethod function. -> class method'''
    return lambda self, *args, **dict: method(self.__class__, *args, **dict)

class Foo:
    def bar(klass):
        print 'In', klass, 'bar()'
    bar = classmethod(bar)

Foo().bar()

output = '''
In junk.Foo bar()
'''

Discussion

Class methods are handy, even on earlier versions of python.

Comments

  1. 1. At 6:14 a.m. on 12 feb 2002, Sébastien Keim said:

    not absolutly similar to 2.2 class methods. In python 2.2, with class methods, you can write things like: Foo.bar() The same thing with the previous classmethod function raise: unbound method must be called with instance as first argument.

    By the way, the code use nested scopes so it won't work with old python versions.

  2. 2. At 6:56 p.m. on 21 feb 2002, Justin Shaw (the author) said:

    Yup ... Yeah, It's got some problems, but I have used this effectiely regardless.

    Thanks for the comment. Maybe you can help me with this one.

    Making __setattr__, and __getattr__ into classmethods I get the following error:

    class Foo:
        def __setattr__(klass, name, value):
            return setattr(klass, name, value)
        __setattr__ = classmethod(__setattr__)
        def __getattr__(klass, name):
            return getattr(klass, name)
        __getattr__ = classmethod(__getattr__)
    f = Foo()
    f.junk = 'junk'
    Traceback (most recent call last):
      File "", line 1, in ?
      File "C:\Python\Python22\junk.py", line 15, in ?
        f.junk = 'junk'
    TypeError: 'classmethod' object is not callable
    
    
    This DOES work with my classmethod?! Any ideas?
    
  3. 3. At 9:10 a.m. on 16 may 2002, Sébastien Bigaret said:

    Python2.1 needs nested_scopes. For this classmethod to work the following statement is needed:

    from __future__ import nested_scopes
    

    cf. http://www.python.org/doc/2.1/ref/nested-scopes.html

Sign in to comment