我认为最好用一个例子来解释。假设我有一个方法来计算两个向量之间的距离并打印它。我也想要这种方法来打印使用的距离测量。距离度量由调用者以可调用对象的形式给予函数。如果callable是某个类的实例,我可以提供__str__
方法,使其打印出距离度量的名称。但是callable也可以是一个函数,在这种情况下我还没有办法改变__str__
。一些代码:
def distance(v1, v2, d):
print d
dist = d(v1, v2)
print dist
return dist
如果d
是一个函数,print d
将打印出<function someFunc at 0x1b68830>
之类的内容。我怎么能改变这个?只需打印出函数的名称就可以了,因为我通常会给它们提供可读的名称。
答案 0 :(得分:2)
我认为函数不能被子类化,这是为了更改函数的__str__
方法所需要做的事情。使类表现得像函数(使用__call__
方法)要容易得多。
函数具有func_name
属性,返回函数的名称。
如果您选择使用func_name
属性,那么您的可调用对象也需要func_name
属性。
由于您已经定义了该类的__str__
方法,因此可以func_name
使str(self)
属性返回def dfunc(v1,v2):
return 1
class FooDist(object):
def __call__(self,v1,v2):
return 1
@property
def func_name(self):
return str(self)
def __str__(self):
return 'My FooDist'
def distance(v1, v2, d):
print d.func_name
dist = d(v1, v2)
print dist
return dist
distance(1,2,dfunc)
# dfunc
distance(1,2,FooDist())
# My FooDist
,如下所示:
{{1}}
答案 1 :(得分:1)
你可以做到
import types
if isinstance(d, types.FunctionType):
print "<function %s>" % d.__name__
答案 2 :(得分:1)
获取函数的名称see this question。 获取班级名称see this question。 把它们放在一起:
def distance(v1, v2, d):
if hasattr(d, '__name__'):
print d.__name__
elif hasattr(d, '__class__'):
print d.__class__.__name__
else:
print d # unsure about this case
dist = d(v1, v2)
print dist
return dist
答案 3 :(得分:0)
您可以统一为类和函数提供自己的属性:
class MyDistanceMeasure:
name = "mine"
#...
def another_distance_measure(x,y):
#...
another_distance_measure.name = "another"
然后:
def distance(v1, v2, d):
print d.name
# or..
print getattr(d, 'name', "unknown")
dist = d(v1, v2)
print dist
return dist