Python函数对象的自定义打印语句
我知道如果我写一个类,我可以像下面这样定义一个自定义的打印函数。
>>> class F:
... def __str__(self):
... return 'This describes the data of F.'
...
>>> f = F()
>>> print f
This describes the data of F.
但是,如果我想对一个函数对象做同样的事情呢?比如说,
>>> def f():
... pass
...
>>> g = f
>>> print g
<function f at 0x7f738d6da5f0>
我希望打印的内容不是像'<function f at 0x7f738d6da5f0>'这样的信息,而是能让我自己指定打印的内容。这样做的原因是,我打算把一堆函数对象存储在一个列表里,然后我想遍历这个列表,打印出人类能理解的函数类型描述,而不想增加额外的复杂性,比如说把函数对象和字符串放在元组里。
非常感谢你能提供的任何帮助。
编辑:我修改了我的例子,以更好地表达我想说的内容,不幸的是,我打错了,写成了'f()',其实我想写的是'f'。我感兴趣的是给函数对象自定义一个标签,而不是自定义返回值(这个显然是怎么做的)。对造成的任何困惑表示抱歉。
5 个回答
2
你不能改变打印一个函数时发生的事情,但你可以让一个类像函数一样工作:
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?
9
其他人建议使用文档字符串,但文档字符串应该更详细地描述函数的功能。如果你想要一个简短的属性来描述这个函数,下面的选项可能正是你需要的:
选项 1
你是说你想要改变一个函数对象的默认描述吗?
>>> def f1(): pass
...
>>> def f2(): pass
...
>>> L = [f1,f2]
>>> print L
[<function f1 at 0x00AA72F0>, <function f2 at 0x00AA73B0>]
如果你想自定义上面列表中函数的描述,可以使用一个叫做装饰器。下面的装饰器会把每个被装饰的函数包装成一个对象,这个对象看起来像原来的函数,但有一个自定义的表示方式:
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
选项 2
另外,你可以在函数中存储属性,并根据需要显示这些属性:
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
选项 3
你也可以用装饰器来实现选项 2:
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
3
有几个错误:
>>> def f():
... pass
...
>>> g = f() <---- g is the return value of running f
>>> print g
None
在第一个例子中,当你调用 print 的时候,其实是在调用 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__
你应该使用文档字符串来说明你的意图。
>>> def f():
... " some doc"
... pass
...
>>>
>>> f.__doc__
' some doc'
>>>
你想做的事情是重写方法 __str__
。
>>> def f():
... "some documentation .."
... pass
...
>>>
>>> f.__str__
<method-wrapper '__str__' of function object at 0x100430140>
>>>