Descriptor
In general, a descriptor is an object attribute with “binding behavior”, one whose attribute access has been overridden by methods in the descriptor protocol. Those methods are
When you want to access/view an attribute of an object, you can just type .__dict__ to check what is stored there. They are all saved in Dictionary format !
class guo(object):
print("nothing to say")
class Circle(guo):
pi = 3.1415926
def __init__ (self, radius):
self.radius = radius
self.circum = 2*self.pi*radius
my = Circle(3)
type(my).mro() # [<class '__main__.Circle'>, <class '__main__.guo'>, <class 'object'>]
But the problem is if we set the new value(here, "radius") to the class object, other attributes is not updated!
my.radius
Out[6]: 3
my.circum
Out[7]: 18.849555600000002
###################
# new value
my.radius = 2
my.circum
Out[9]: 18.849555600000002 ## it is wrong !
Solution :
class Circle(guo):
pi = 3.1415926
def __init__ (self, radius):
self.radius = radius
@property
def circum(self):
return 2*self.pi*radius
Now run it again!
__get__(), __set__(), and __delete__(). If any of those methods are defined for an object, it is said to be a descriptor. from https://docs.python.org/2/howto/descriptor.htmlWhen you want to access/view an attribute of an object, you can just type .__dict__ to check what is stored there. They are all saved in Dictionary format !
class guo(object):
print("nothing to say")
class Circle(guo):
pi = 3.1415926
def __init__ (self, radius):
self.radius = radius
self.circum = 2*self.pi*radius
my = Circle(3)
type(my).mro() # [<class '__main__.Circle'>, <class '__main__.guo'>, <class 'object'>]
But the problem is if we set the new value(here, "radius") to the class object, other attributes is not updated!
my.radius
Out[6]: 3
my.circum
Out[7]: 18.849555600000002
###################
# new value
my.radius = 2
my.circum
Out[9]: 18.849555600000002 ## it is wrong !
Solution :
class Circle(guo):
pi = 3.1415926
def __init__ (self, radius):
self.radius = radius
@property
def circum(self):
return 2*self.pi*radius
Now run it again!
my = Circle(3) print(my.circum) # 18.849555600000002 my.radius = 2print(my.circum) # 12.5663704
Yes, it is right now !!
Find a good example to implement the descriptor :
# https://www.smallsurething.com/python-descriptors-made-simple/
from weakref import WeakKeyDictionary class Price(object): def __init__(self): self.default = 0 self.values = WeakKeyDictionary() def __get__(self, instance, owner): return self.values.get(instance, self.default) def __set__(self, instance, value): if value < 0 or value > 100: raise ValueError("Price must be between 0 and 100.") self.values[instance] = value def __delete__(self, instance): del self.values[instance] class Book(object): price = Price() def __init__(self, author, title, price): self.author = author self.title = title self.price = price def __str__(self): return "{0} - {1}".format(self.author, self.title) b = Book("William Faulkner", "The Sound and the Fury", 12) b.price # 12b.price = -12b.price = 101
留言
張貼留言