python 中的 __name__ 有什么重要意义?

What is so important about __name__ in python?

提问人:Nafees Anwar 提问时间:2/21/2020 更新时间:2/21/2020 访问量:343

问:

为每个 python 函数分配一个属性。例如__name__

>>> def f(*args, **kwargs):
...     pass
... 
>>> f.__name__
'f'

现在,如果我们用一些装饰器来装饰这个函数,我们基本上会返回另一个具有不同的函数__name__

>>> def d(f):
...     def w(*args, **kwargs):
...         f(*args, **kwargs)
...     return w
... 
>>> f = d(f)
>>> f.__name__
'w'

强烈建议使用 from 来修饰返回的函数,这样可以将 和 等信息复制到原始函数中。wrapsfunctools__name____doc__

>>> from functools import wraps
>>> def d(f):
...     @wraps(f)
...     def w(*args, **kwargs):
...         f(*args, **kwargs)
...     return w
... 
>>> f = d(f)
>>> f.__name__
'f' 

我的问题是,如果我们不习惯复制信息,我们会遇到哪些严重的麻烦?简单地说,它应该被复制的如此重要吗?简单的代码,就像我的示例一样,如果我们不使用 .wraps__name__wrap

我可以想到一个问题是序列化。例如,Django 不允许使用 lambda 表达式(它们是无名的)用作模型字段的默认值。

有人可以添加一些更有问题的例子吗?同样的问题也适用于类装饰器。

Python 函数 装饰器

评论

7赞 deceze 2/21/2020
提示:异常中的堆栈跟踪...
3赞 Iguananaut 2/21/2020
API 文档是另一个例子。如果您希望记录包装函数而不是包装函数,则它应该继承并从包装函数继承。它只是有助于清楚起见,而不是严格要求,除非你专门使用基于函数名称进行调度的代码。__name____doc__
0赞 Nafees Anwar 2/21/2020
@Iguananaut我所看到的,从堆栈跟踪和文档的角度来看,它在人类层面上是有帮助的。在编译或执行中对计算机级别没有影响。
2赞 deceze 2/21/2020
除非你以编程方式将 for 任何东西(你合法地可以这样做),否则,它只适用于人类。__name__
1赞 Iguananaut 2/21/2020
对于序列化来说,名称甚至并不一定那么重要(尽管这取决于“序列化”的含义)。例如,在酸洗的情况下,您可以酸洗在模块级别定义的命名函数,因为函数的默认酸洗方法的工作方式是它只是酸洗模块名称和函数名称,然后在取消酸洗时使用它来导入函数。你不能轻易地用 lambda 做到这一点,因为 pickle 必须包含 lambda 本身的代码(这是可行的,人们已经做到了,但有局限性)。

答: 暂无答案