【发布时间】:2016-02-03 18:19:14
【问题描述】:
我是 Python 描述符的新手。下面的问题是为了帮助我更好地理解它们的工作原理。
在 Python 3.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 为何在所有实例中都将“名称”设置为一个公共值?
根据我对描述符的理解,描述符版本 001 会将名称存储在 Person 对象实例的属性中:
sam.__name = "sam"
merry.__name = "merry"
而描述符版本 002 会将名称存储在 Person 对象实例的属性的属性中:
same.name.value = "sam"
merry.name.value = "merry"
因此,对于 Python 描述符的工作原理,我显然有一些不明白的地方。谁能给我一些澄清?
【问题讨论】:
标签: class python-3.x attributes instance descriptor