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?
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".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With