在python3的手册中:
https://docs.python.org/3/howto/descriptor.html#definition-and-introduction
一般来说,描述符是具有描述符协议中的方法之一的属性值。这些方法是
__get__()
、__set__()
和 __delete__()
。如果为属性定义了任何这些方法,则称其为描述符。
class Room:
def __init__(self,name):
self.name = name
def __getattribute__(self,attr):
return object.__getattribute__(self,attr)
def __setattr__(self,attr,value):
return object.__setattr__(self,attr,value)
__getattribute__
和__setattr__
是python的魔法方法,内置函数,Room
类使用魔法方法来实现__get__
和__set__
,严格来说,Room
类是一个描述符吗?
Room 类不是描述符。 Python 中的描述符是至少实现一种描述符方法的类:get()、set() 或 delete()。这些方法定义描述符如何与所有者对象的属性交互。
Room类中,getattribute()和setattr()方法分别用于拦截属性访问和赋值操作。然而,这些方法本身并不能使 Room 成为描述符。它们是针对每个属性访问和分配自动调用的特殊方法,无论该属性是否是描述符。
要使 Room 类成为描述符,您需要至少实现一种描述符方法(get()、set() 或 delete())。就目前情况而言,示例中的 Room 类只是使用魔术方法像常规类一样处理属性访问和分配,但它不符合被视为描述符的标准。
要创建描述符,您需要定义一个或多个前面提到的描述符方法(通常在单独的类中),然后使用该类的实例作为另一个类的属性。当访问、设置或删除所有者对象的该属性时,将调用描述符方法......来自 google treanslate
不可能通过实现
__get__
方法来“伪造”潜在描述符类中 __set__
、__delete__
或 __getattribute__
方法的存在。您也无法使用其他特殊方法来执行此操作,例如 __len__
或 __add__
。
这是因为双下划线名称只是 Python 级别的包装器,Python 解释器使用这些较低级别的槽来描述类的行为。当一个方法被分配给像
__get__
或 __add__
这样的特殊名称时,类结构中相应的槽就会更新,以便解释器知道在相关语言功能(例如描述符行为或添加)时调用该方法在对象上调用。当发生这种情况时,该方法的内部查找不会通过 __getattribute__
方法。因此,即使 __getattribute__
尝试提供 __get__
(或 __add__
或 __len__
)方法,它也不会起作用。