gpt4 book ai didi

python - 为什么这个类描述符 __get__ 方法返回 self?

转载 作者:行者123 更新时间:2023-12-04 10:46:15 24 4
gpt4 key购买 nike

我正在阅读 O Reilley Python Cookbook,我对以下代码有疑问:

class Typed:
def __init__(self, name, expected_type):
self.name = name
self.expected_type = expected_type

def __get__(self, instance, cls):
if instance is None:
return self
else:
return instance.__dict__[self.name]

def __set__(self, instance, value):
if not isinstance(value, self.expected_type):
raise TypeError('Expected ' + str(self.expected_type))
instance.__dict__[self.name] = value

def __delete__(self, instance):
del instance.__dict__[self.name]

# Class decorator that applies it to selected attributes
def typeassert(**kwargs):
def decorate(cls):
for name, expected_type in kwargs.items():
# Attach a Typed descriptor to the class
setattr(cls, name, Typed(name, expected_type))
return cls
return decorate

# Example use
@typeassert(name=str, shares=int, price=float)
class Stock:
def __init__(self, name, shares, price):
self.name = name
self.shares = shares
self.price = price

if __name__ == '__main__':
s = Stock('ACME', 100, 490.1)
print(s.name, s.shares, s.price)
s.shares = 50
try:
s.shares = 'a lot'
except TypeError as e:
print(e)

我对这部分感到困惑:

def __get__(self, instance, cls):
if instance is None:
return self
else:
return instance.__dict__[self.name]

如果未设置实例(即无),则它说返回“self”,鉴于 self 代表类描述符,究竟返回了什么?

最佳答案

是的,它返回描述符实例。
self 的第二个参数(在 __get__ 之后的第一个)是查找描述符的实例 - 或 None如果它在类上查找。

因此,在给定的情况下,它会返回描述符,以防您在类上查找描述符。

只是为了说明:

class Descriptor:
def __get__(self, instance, owner):
if instance is None:
return self
return 10

class Test:
test = Descriptor()


>>> Test.test
<__main__.Descriptor at 0x2769b7d44c8>

>>> Test.__dict__['test']
<__main__.Descriptor at 0x2769b7d44c8>

现在,如果它没有使用 return self那里看起来像这样:
class Descriptor:
def __get__(self, instance, owner):
return 10

class Test:
test = Descriptor()


>>> Test.test
10

>>> Test.__dict__['test']
<__main__.Descriptor at 0x2769b7de208>

这个的原因 return self经常这样做是因为它允许获取描述符实例而无需在 __dict__ 中搜索。 (可能在所有父类(super class)中)。在大多数情况下,在类中查找属性时做任何事情都没有意义,因此返回实例是一个好主意。

这也是内置的 property确实(以及函数描述符):
class A:
@property
def testproperty(self):
return 10

def testmethod(self):
return 10

>>> A.testproperty
<property at 0x2769b7db9a8>
>>> A.testproperty.__get__(None, A)
<property at 0x2769b7db9a8>

>>> A.testmethod
<function __main__.A.testmethod(self)>
>>> A.testmethod.__get__(None, A)
<function __main__.A.testmethod(self)>

在那些在类上查找属性时应该发生有意义的事情的情况下(例如内置的 staticmethodclassmethod 描述符)当然是不同的, self不应该回到那里!

关于python - 为什么这个类描述符 __get__ 方法返回 self?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59689680/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com