Reputation: 1678
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.
Upvotes: 4
Views: 12426
Reputation: 178429
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
Upvotes: 9
Reputation: 107786
You cant change what happens when you print a function, but you can make a class behave like a function:
class f(object):
def __str__(self):
return "I'm a function!"
def __call__(self):
print "who called?"
print f # I'm a function!
f() # who called?
Upvotes: 2
Reputation: 61654
>>> g = f # no ()! That *calls* the function.
>>> print g
<function f at 0x########>
Upvotes: 0
Reputation: 66739
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>
>>>
Upvotes: 3
Reputation: 4883
Functions return values. The value assigned to g
variable is going to be printed. If you want to print something, just make sure the function f
, returns a string.
>>> def f():
... return "Print me"
...
>>> g = f()
>>> print g
Print me
Upvotes: 0