你能在函数中定义 __repr__ 并且函数是 class 吗?

can you define __repr__ in a function and is a function a class?

如果我有一个名为 foo 的函数:

def foo():
    return "foo function"

并且如果看到它 returns 一个甚至没有调用函数的字符串意味着 __repr__ 的定义就像你在这个例子中看到的那样:

>>> func
<function func at 0x000001F43B1968B8>
>>> func.__repr__()
'<function func at 0x000001F43B1968B8>'

所以现在我想到了 2 个问题

  1. 函数是 class 类型吗?
  2. 如果可以,我如何在函数
  3. 中定义__repr__

两个问题的一点解释:

1: 因为如果你这样做: func. 然后在 IDE 中按 ctrl + space 你会看到 class 也有的一切所以我得到的问题是一个函数不是一个(简单)class?

2: 我可以这样做吗:

def foo():
    def __repr__():
        return "lol"
    foo.__repr__ = __repr__
    return "foo function"

它在 IDLE 中工作,但它不会在您调用它之前更改 __repr__ 输出,因此是否可以在调用该函数之前更改 __repr__

回答:

回答问题 2:不,不使用 def

问题 1 的答案:是的,您可以将函数视为 class,因为 python 是基于 classes

option 1(using classes):

因为这个:

class foo():
    def __init__(self):
        self = "foo"

还有这个:

class _foo():
    def __init__(self):
        self.foo = "foo"
    def __call__(self):
        return self.foo
foo = _foo()

对于用户来说等同于:

def foo():
    return "foo"

所以如果你真的想要一些看起来像函数但带有自定义版本的东西 __repr__ 你只需要做这样的东西:

class _foo():
    def __init__(self):
        self.foo = "foo"
    def __repr__(self):
        return "func(foo)"
    def __call__(self):
        return self.foo
foo = _foo()

因为现在如果您在粘贴后在 IDLE 中执行 foo,您将看到以下输出:


>>> foo
func(foo)
>>> 

using a wrapper class:

在此示例中,我使用 class 作为包装器:

class func_wrapper():
    
    def __init__(self,func,repr_msg):
        self.func = func
        self.repr_msg = repr_msg
        
        
        self = repr_msg
        
    def __call__(self,*args,**kwargs):
        return self.func(*args,**kwargs)
    def __repr__(self):
        return self.repr_msg




def repr(msg):
    def dec(fn):
        
        wrapper = func_wrapper(func = fn,repr_msg = msg)
        
        return wrapper
    return dec


@repr("LOL")
def foo():
    return "foo function"

print(foo)
print(foo.__repr__())
print(foo())

它会打印:

LOL
LOL
foo function

解释:

(几乎) python 中的所有内容都是 class 尝试使用 type(object) 你会看到几乎每个“对象”都说它是 class.

所以我想说的是 python 几乎是基于 classes 它们无处不在,因为如果你试图从不是 class 的东西中找到非 class内置。因为只有一些内置函数不被视为 classes

回顾:

总结一下我的回答:

不,您不能使用 def 在函数被调用之前调用 __repr__,但是您可以制作一个真正看起来像函数的 class,然后您可以制作一个 class 对用户来说就像一个函数

is a function a class type? Yes

print(type(foo))

生产

<class 'function'>

is it possible to change __repr__ before the function has been called?

是的,例如使用装饰器:

from functools import wraps


def repr(msg):
    def dec(fn):
        @wraps(fn)
        def new_fn(*args, **kwargs):
            return fn(*args, **kwargs)

        new_fn.__repr__ = lambda: msg
        return new_fn
    return dec


@repr("LOL")
def foo():
    return "foo function"

print(foo)
print(foo.__repr__())
print(foo())

生产

<function foo at 0x7f556d959ef0>
LOL
foo function