I know that if I write a class, I can definite a custom print function as below.
>>> class F:
... def __str__(self):
... return 'This describes the data of F.'
...
>>> f = F()
>>> print f
This describes the data of F.
But, what if I want to do the same for a function object? For example,
>>> def f():
... pass
...
>>> g = f
>>> print g
<function f at 0x7f738d6da5f0>
Instead of '<function f at 0x7f738d6da5f0>', I'd like to somehow specify what was printed. The motivation for doing this is that I'm going to store a bunch of function objects in a list, and I'd like to iterate over the list and print human-readable descriptions of the types of functions without adding additional complexity, e.g., tuples of function objects and strings.
Thanks in advance for any help you can provide.
Edit: I changed my example to reflect what I was trying to convey, unfortunately I typed 'f()' when I meant 'f'. I am interested in a custom label for the function object, not customizing the return (which it is obvious how to do). Sorry for any confusion this has caused.
Others have suggested doc strings, but a doc string should probably be more descriptive of what the function does. If you want a short attribute describing the function, one of the options below may be what you are looking for:
Are you saying you want to change the default description of a function object?
>>> def f1(): pass
...
>>> def f2(): pass
...
>>> L = [f1,f2]
>>> print L
[<function f1 at 0x00AA72F0>, <function f2 at 0x00AA73B0>]
If you want to customize the description of the functions in the list above, use a decorator. The decorator below wraps each function decorated into an object that acts like the original function, but has a custom representation:
def doc(s):
class __doc(object):
def __init__(self,f):
self.func = f
self.desc = s
def __call__(self,*args,**kwargs):
return self.func(*args,**kwargs)
def __repr__(self):
return '<function {0} "{1}">'.format(self.func.func_name,self.desc)
return __doc
@doc('a+b')
def sum(a,b):
return a + b
@doc('a-b')
def diff(a,b):
return a - b
L = [sum,diff]
print L
for f in L:
print f(5,3)
[<function sum "a+b">, <function diff "a-b">]
8
2
Alternatively, you can store attributes in your functions and display them as needed:
def sum(a,b):
return a + b
sum.desc = 'a+b'
def diff(a,b):
return a-b
diff.desc = 'a-b'
L = [sum,diff]
for f in L:
print f.desc,f(8,3)
a+b 11
a-b 5
You can do option 2 with a decorator also:
def doc(s):
def __doc(f):
f.desc = s
return f
return __doc
@doc('a+b')
def sum2(a,b):
return a + b
@doc('a-b')
def diff2(a,b):
return a - b
L = [sum2,diff2]
for f in L:
print f.desc,f(8,3)
a+b 11
a-b 5
Few errors:
>>> def f():
... pass
...
>>> g = f() <---- g is the return value of running f
>>> print g
None
in the first case, when you call print, you are calling a string representation of f
>>> f = F()
>>> print f <----- f is an instance of class F and
<----- print f tries to provide a suitable string representation
<----- by calling f.__str__
You should use doc strings for your motives
>>> def f():
... " some doc"
... pass
...
>>>
>>> f.__doc__
' some doc'
>>>
What you are trying to do is override the method wrapper __str__
.
>>> def f():
... "some documentation .."
... pass
...
>>>
>>> f.__str__
<method-wrapper '__str__' of function object at 0x100430140>
>>>
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