【问题标题】:why use __xxx__ define funtion’s property?为什么要用 __xxx__ 定义函数的属性?
【发布时间】:2018-11-04 11:00:19
【问题描述】:

我是这里的新蟒蛇。我有一个问题。代码是这样的:

def get(path):
    '''
    Define decorator @get('/path')
    '''
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            return func(*args, **kw)
        wrapper.__method__ = 'GET'
        wrapper.__route__ = path
        return wrapper
    return decorator

这是一个装饰器,我不懂

"

  wrapper.__method__ = 'GET'
     wrapper.__route__ = path

"__xxx__"一般用来定义特殊的方法和属性,为什么代码中定义函数的属性使用样式?这不是提倡吗? 并且可以为函数动态添加属性以及为类动态添加属性吗? 太感谢了~

【问题讨论】:

  • 如果您是 Python 新手,那么您会看到完全错误的 Python 代码。
  • 谢谢。我只是不明白为什么代码添加函数的属性像这种风格。双下划线开头和结尾通常用于特殊变量?就像 nameinit
  • 是的,函数是第一类对象,您可以随意设置和修改属性。同时,该语言特别不赞成制作自定义的 dunder 属性,因此编写此代码的人指望 Python 本身不会引入任何冲突的更改。不要做那样的事情。但是通常给函数添加属性是完全可以的。
  • @lee。双下划线(dunder)属性都是语言明确保留的。
  • 知道了。非常感谢。你帮了我很多~@Mad Physicist

标签: python python-3.x function python-decorators


【解决方案1】:

这里实际上有两个问题:一个是关于为函数分配任意属性的问题,另一个是关于分配特殊/双下划线 (dunder)/magic 属性的问题。

为函数分配属性非常好。根据docs

函数是一等对象。

这并不自动意味着您可以为它们分配属性,但这是一个很好的指示。函数对象有一个writable __dict__1,这使得设置属性成为可能。这是一个有意且经常使用的功能。以下 SO 问题详细说明了该主题:Python function attributes - uses and abuses

所示代码的问题在于不正确地使用了 dunder 属性。基本上,将 dunder 属性用于除官方记录之外的任何用途是 bad idea

任何__*__名称的使用,在任何情况下,如果没有遵循明确记录的使用,可能会在没有警告的情况下被破坏。

这里有两个特别的问题。主要问题是添加未记录的 dunder 属性可能会与functools.wraps 设置的正常可调用属性发生冲突(在Data Model1 中列出)。第二个问题是添加 dunder 属性可能会在某些情况下为对象添加不良行为,因为它们被解释器用作标志。

有许多替代命名约定需要注意,其中一些可能比 dunder 方法更合适:

  • 例如,将__method__ 重命名为_method 会使其“按照约定私有”,因为Python 并不能真正识别privacy 的概念。
  • _method 的修改版本将是 _method_。这是内置 enum 包使用的约定,正是为了避免破坏保留名称。
  • 使用简单的名称当然总是可以的:method 而不是 __method__
  • 不起作用的命名方案是__method。这会由解释器触发name mangling,因此调用者将无法访问该名称。这比只使用笨拙的名字要糟糕得多,这对于我目前所知道的任何解释器都不会造成真正的问题。

TL;DR

为函数分配属性非常有用且完全受支持。然而,分配给 dunder 属性充其量是值得怀疑的。


1 向下滚动到“可调用类型”

【讨论】:

  • @Lee。如果满足您的需求,请选择答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-29
  • 1970-01-01
  • 2019-10-28
  • 1970-01-01
  • 2011-03-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多