The best way to invoke methods in Python class declarations?

Say I am declaring a class C and a few of the declarations are very similar. I'd like to use a function f to reduce code repetition for these declarations. It's possible to just declare and use f as usual:

>>> class C(object):
...     def f(num):
...             return '<' + str(num) + '>'
...     v = f(9)
...     w = f(42)
... 
>>> C.v
'<9>'
>>> C.w
'<42>'
>>> C.f(4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method f() must be called with C instance as first argument (got int instance instead)

Oops! I've inadvertently exposed f to the outside world, but it doesn't take a self argument (and can't for obvious reasons). One possibility would be to del the function after I use it:

>>> class C(object):
...     def f(num):
...             return '<' + str(num) + '>'
...     v = f(9)
...     del f
... 
>>> C.v
'<9>'
>>> C.f
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'C' has no attribute 'f'

But what if I want to use f again later, after the declaration? It won't do to delete the function. I could make it "private" (i.e., prefix its name with __) and give it the @staticmethod treatment, but invoking staticmethod objects through abnormal channels gets very funky:

>>> class C(object):
...     @staticmethod
...     def __f(num):
...             return '<' + str(num) + '>'
...     v = __f.__get__(1)(9)   # argument to __get__ is ignored...
... 
>>> C.v
'<9>'

I have to use the above craziness because staticmethod objects, which are descriptors, are not themselves callable. I need to recover the function wrapped by the staticmethod object before I can call it.

There has got to be a better way to do this. How can I cleanly declare a function in a class, use it during its declaration, and also use it later from within the class? Should I even be doing this?

Answers


Quite simply, the solution is that f does not need to be a member of the class. I am assuming that your thought-process has gone through a Javaish language filter causing the mental block. It goes a little something like this:

def f(n):
    return '<' + str(num) + '>'

class C(object):

    v = f(9)
    w = f(42)

Then when you want to use f again, just use it

>>> f(4)
'<4>'

I think the moral of the tale is "In Python, you don't have to force everything into a class".


Need Your Help

Open a new page in a new window, print it and closed it

javascript jquery html

I still can't get this code to work, I am trying to use the "onClick" to swap the image once clicked, open this new page in a new window, print this new opened window and closed it. It opens the ne...

scheduling tasks on JBoss with clustering

java jboss ejb-3.0 scheduling

I need to be able to run some scheduled tasks (reports) for an EJB application running on JBoss 4.2.