Python 3.x - 使用 setattr/getattr 与内部值的属性描述符

Python 3.x - Attribute descriptor using setattr/getattr vs internal value

我是 Python 描述符的新手。下面的问题是为了帮助我更好地理解它们是如何工作的。

在Python3.x中,我使用的是属性描述符。这个描述符的特殊之处在于它的 set 方法包含大量健全性检查,以确保要设置到属性的值遵守某些规则。构造函数使用 setattr 和 getattr 来操作属性。构造函数运行良好,其代码报告如下。

class AttributeDescriptor():    <----- Version 001 of this class

   def __init__(self, attname):

      self.__attname = "__" + attname

   def __set__(self, obj, attvalue):   

       #Some data quality checks, not provided here...

      setattr(obj, self.__attname, attval)   

   def __get__(self, obj, owner):   

      return getattr(obj, self.__attname) 


class Hobbit():

   def __init__(self):

      pass

   name = AttributeDescriptor("name")

sam = Hobbit()
merry = Hobbit()

sam.name = "Sam"
merry.name = "Merry"

print(sam.name)        ----> Returns "Sam"
print(merry.name)      ----> Returns "Merry"
print(sam.name)        ----> Returns "Sam"

我还尝试使用以下代码定义构造函数,它为 "name" 属性返回了错误的值。事实上,所有霍比特人的名字都被设置为等于已定义的姓氏。

class AttributeDescriptor():    <---- Version 002 of this class

   def __set__(self, obj, attvalue):   

       #Some data quality checks, not provided here...

      self.value = attvalue 

   def __get__(self, obj, owner):   

      return self.value  


class Hobbit():

   def __init__(self):

      pass

   name = AttributeDescriptor()

sam = Hobbit()
merry = Hobbit()

sam.name = "Sam"
merry.name = "Merry"

print(sam.name)        ----> Returned "Merry"
print(merry.name)      ----> Returned "Merry"
print(sam.name)        ----> Returned "Merry"

我的问题是:为什么描述符版本 002 设置 "name" 等于其所有实例中的公共值?

根据我对描述符的理解,描述符版本 001 会将名称存储在 Person 对象实例的属性中:

sam.__name = "sam"
merry.__name = "merry"

而描述符版本 002 会将名称存储在 Person 对象实例的 属性 的一个属性中:

same.name.value = "sam"
merry.name.value = "merry"

因此,对于 Python 描述符的工作原理,显然有一些我不明白的地方。任何人都可以向我提供一些说明吗?

在您的第二个示例中,您正在为 AttributeDescriptor 实例本身设置值。

您的程序中只有一个 AttributeDescriptor() 实例,因此每次您使用他的 set 方法时它都会更改相同的值

class霍比特人():

  def __init__(self):

     pass

  name = AttributeDescriptor("name") # <---- happens ONLY once!!!

python 中的 class 定义只发生*一次 ...

*除非没有。但是让我们坚持更简单的真相:)