小能豆

函数中的预定义描述符如何工作?

py

Python 函数有一个描述符。我相信在大多数情况下我不应该直接使用它,但我想知道这个功能是如何工作的?我尝试对这样的对象进行一些操作:

1.

   def a():
   return ‘x’

   a.get.doc
   ‘descr.get(obj[, type]) -> value’

obj 是什么,类型是什么?

a.get()
TypeError: expected at least 1 arguments, got 0

a.get(‘s’)

a.get(‘s’)()
TypeError: a() takes no arguments (1 given)
```

当然,我无法对不带参数的函数执行此技巧。是否只需要调用带参数的函数?

def d(arg1, arg2, arg3):
return arg1, arg2, arg3
d.get(‘s’)(‘x’, ‘a’)
(‘s’, ‘x’, ‘a’)
```

为什么第一个参数直接由 接收__get__,而其他所有参数都由返回的对象接收?


阅读 6

收藏
2024-11-14

共1个答案

小能豆

描述符(descriptor)是 Python 中用于实现属性访问管理的一种机制。它们通常是定义在类中的方法,它们会在访问属性时自动被调用。常见的描述符包括 __get____set____delete__,它们定义了如何获取、设置和删除一个属性的行为。

对你的问题的解答:

  1. 关于 objtype

当你执行 a.get.docget 是函数 a 的一个描述符,doc 是描述符的属性。在 Python 中,get 描述符通过 __get__ 方法工作,obj 是调用 get 描述符的对象,而 type 通常指的是该对象的类型。

  • obj 是一个对象实例,它是 get 描述符被访问时实际发生的上下文(即实例化对象)。
  • typeobj 的类型(即类),它提供上下文中的类型信息。

当你调用 a.get('s') 时,a 仍然是一个函数,get 会触发它的 __get__ 方法,'s' 作为参数传递给它。如果 get 是一个描述符,它会获取这个参数并进行处理。

  1. 关于 get 和参数

  2. 如果你调用 a.get(),会出现 TypeError: expected at least 1 arguments, got 0,因为 get 需要至少一个参数。在描述符的 __get__ 方法中,通常会有 self(描述符自身)和 obj(目标对象)两个参数,所以你不能直接调用 get 方法而不提供这些参数。

  3. 当你调用 a.get('s')() 时,Python 会试图调用返回的对象。返回的对象是一个可调用的对象,你可能得到另一个 TypeError,因为它期望传入一些参数,而你传入了 's'

  4. 关于第二个例子 d

python def d(arg1, arg2, arg3): return arg1, arg2, arg3 d.get('s')('x', 'a')

这里 d 是一个函数,get 描述符的工作是返回该函数的一个新实例或其他可调用的对象。's' 被传递给 d.get('s'),然后它返回一个可调用的对象(通常是一个函数)。当你调用 ('x', 'a') 时,d 函数会被执行,'s', 'x', 'a' 作为其参数传递给 d

  • 为什么第一个参数直接由接收 __get__,而其他所有参数都由返回的对象接收?

    因为在描述符 get 中,__get__ 方法默认会返回原函数或对象本身,并且它会捕获并返回新的对象或函数。这个返回的对象会使用接收到的参数(比如 'x''a')执行其操作。

总结:

  • __get__ 是一个描述符的核心,它控制了如何从对象中提取和返回数据。
  • 对于带有描述符的对象,调用描述符方法(如 get)时会传递 obj(对象本身)作为参数,type 则表示该对象的类。
  • 如果你想调用带有参数的函数或者描述符,你需要确保正确传递必要的参数。
2024-11-14