如何替换函数的__str__

时间:2014-04-01 21:49:46

标签: python string function

我想将python函数的字符串表示更改为函数名。

例如某些功能

def blah(x):
 ...

str(blah)目前提供

<function blah at 0x10127b578>

所以我这样替换__str__

blah.__str__=lambda: 'blah'

但它不会被str(blah)调用。

是否可以更改功能的__str__

4 个答案:

答案 0 :(得分:6)

替换__str__之类的内容永远不会对任何类型的对象起作用。内置函数类型并不特殊:

>>> class Foo(object):
    pass

>>> f = Foo()
>>> f.__str__ = lambda: 'f'
>>> str(f)
'<__main__.Foo object at 0x0000000002D13F28>'
>>> f.__str__()
'f'    

str内置程序不通过常用的查找协议查找__str__,它直接跳过查看其参数的类。所以你不能覆盖&#34;单个对象上的__str__方法;你必须在类上设置它以应用于该类的所有对象。 1

但话说回来,内置函数类型并不特殊。你可以创建一个主要像函数一样的类,然后使用它:

class Function(object):
    def __init__(self, raw_function):
        self.raw_function = raw_function
    def __call__(self, *args, **kwargs):
        return self.raw_function(*args, **kwargs)
    def __str__(self):
        return self.raw_function.__name__

__call__方法意味着您可以像调用函数一样调用此类的对象。这个只是将它直接接收的任何参数传递给底层的原始函数,并返回它返回的任何内容(或抛出它抛出的任何异常)。由于这个类只使用一个函数作为参数,它也适合装饰器的模式:

@Function
def blah(x):
    return x + 1

有了这个:

>>> blah
<__main__.Function object at 0x0000000002D13EB8>
>>> str(blah)
'blah'
>>> blah(33)
34

1 内置函数类型 在某些方面是特殊的(我撒谎),其中一个是你不能分配给它的属性(&# 39;是本身的属性,而不是任何特定函数对象的属性。所以在你想到也许你可以将内置函数类型monkeypatch以便str按照你想要的方式运行所有函数时,这可能会很好。它可能是最好的;将内容修改为全局和基本内容,因为内置函数类型将是发明一些非常奇怪的错误的好方法。

答案 1 :(得分:5)

正如乔兰所说:

class NamedFunction:
    def __init__(self, name, f):
        self.f = f
        self.name = name

    def __call__(self, *args, **kwargs):
        return self.f(*args, **kwargs)

    def __str__(self):
        return self.name


f = NamedFunction("lambda: 'blah'", lambda: 'blah')
print(f())
print(f)

答案 2 :(得分:3)

class FNMagic:
     def __init__(self,fn,fn_name):
         self.fn = fn 
         self.fn_name = fn_name
     def __call__(self,*args,**kwargs):
         return self.fn(*args,**kwargs)
     def __str__(self):
         return self.fn_name


def blah(x):
    return x

blah = FNMagic(blah,"blah!")
print blah

你可以做一个简单的装饰

class NamedFn:
    def __init__(self,name):
       self.fn_name = name
    def __call__(self,fn):
        return FNMagic(fn,self.fn_name)

@NamedFn("some_name!!!")
def blah2(x,y):
     return x*y

print blah2

答案 3 :(得分:1)

如前所述,答案是否定的。如果您只想将函数的名称作为字符串,则可以使用blah.__name__