首页 新闻 会员 周边

property类和Descriptor区别

0
[已关闭问题] 关闭于 2026-06-08 10:20

当你访问 s.pro 时,​Python 调用 property 的 get 。​
● property 的 get 内部会去查找之前存好的 _fget ,​然后执行它。​,​这个应该是property类的内部实现吧,​而我的Descriptor没有这种实现,​所以就是直接调用__get__,__set__,​__del__

问题补充:

我们可以把这两者的区别总结为:“硬编码逻辑” vs “动态存储逻辑”。

property 的内部实现(动态存储)
正如你所推测的, property 本质上就是一个预先写好的、功能强大的描述符类。它的内部源码逻辑大致如下(伪代码):

class property:
def __init__(self, fget=None, fset=None, fdel=None):
# 1. 【关键】它把传入的方法保存到了自己的实例变量中
self.fget = fget
self.fset = fset
self.fdel = fdel

def __get__(self, obj, objtype=None):
if obj is None:
return self
# 2. 【执行】调用时,它去取之前存好的 fget 并运行
if self.fget is None:
raise AttributeError("unreadable attribute")
return self.fget(obj)

def __set__(self, obj, value):
# 3. 【执行】调用时,它去取之前存好的 fset 并运行
if self.fset is None:
raise AttributeError("can't set attribute")
self.fset(obj, value)

结论:  property  的  get  方法本身不包含业务逻辑,它只是一个 “调度器”。它负责去查找你在创建对象时传进去的那个函数( getName ),然后替你去执行它。

 

*Tesla*的主页 *Tesla* | 小虾三级 | 园豆:1726
提问于:2026-06-08 10:17
< >
分享
所有回答(1)
0

你的 Descriptor 的实现(硬编码)
再看你写的 Descriptor 类:

class Descriptor():
# 没有 __init__,所以无法接收外部参数
def __get__(self, instance, owner):
print("sssssssssss") # 逻辑是写死在这里的

 

结论: 你的  Descriptor  的  get  方法既是 “调度器” 也是 “执行者”。因为你在定义类的时候就把  print("...")  写死了,而且没有通过  init  接收外部函数来替换这个行为,所以无论你怎么用,它永远只打印那串字符。

● 相通点: 它们都是描述符,都会拦截属性的访问( t.de 或 s.pro )。
● 不同点:
● property :是一个通用的容器。它通过 init 接收函数,在 get 中动态调用这些函数。
● 你的 Descriptor :是一个特定的工具。它的行为在定义类的时候就已经静态固定了(写死在方法体里),除非你修改类的源代码,否则它的行为不会变。

 

同归(底层机制一致)
无论怎么写,当 Python 解释器遇到 t.de 或 s.pro 时,它只认一条规则:

“这个属性是不是描述符?如果是,就调用它的  get  方法。”

*Tesla* | 园豆:1726 (小虾三级) | 2026-06-08 10:19
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册