Python's Descriptors - Part I - Let the hunt begin
What and why is descriptor ?
I have just been working with Python for more than one year. Basically, it’s a very nice programming language with short and clear syntax. However, when I tried to write some data objects for Posify project, there is the beginning of many troubles.
In Python, an object have not to define its attributes. Actually, you can define object’s attributes when init an object or add more attributes whenever after init with any type you want (such an easygoing language).
1 | class Dog(object): |
This is really hurt when I want to create data object, that means I must handle what attributes should be in an object and its type. I just missed writing a function to verify each object (its attributes and its attributes’ type), then put it in every __init__
like:
1 | class Dog(object): |
It’s so ugly, right? And when I look at Mongoengine ORM, it’s a wonderful implemetation:
1 | class Dog(Base): |
I asked myself how to build my object like this, and I find out Descriptors. Descriptor’s definition is an object attribute with “binding behavior”. Yes, “binding behavior” is what we want here, so let’s create some descriptor.
First, let take a look in Python’s object built-in. There are many special method, but we just need three method to create descriptors called to descriptor protocal: get(), set() and delete(). In another words, if any of those methods are defined for an object, it is said to be a descriptor.
Let’s craft some Descriptors
So, I keep in my mind the words “binding behavior”, and look at Mongoengine code, it’s seem like create an object with overrided set()
and get()
function, so I try:
1 | class StringField(object): |
Yay, we done. Descriptor is so easy. OR NOT? Now, just change some code and see:
1 | a = Dog() |
Omg, it’s went wrong. This problem caused by all Dog
instances share the same kind
instance. When one Dog
set his kind, another Dog
will share it. It’s so frustrate.
So we must store kind for each separated Dog
, something like dictionary with key is object and value is attributes to avoid this misunderstood. OK, let go deeper in this treasure hunting and find out the magic behind Descriptor.
(Part II will coming soon …)