Python descriptor (2)

Source: Internet
Author: User
Tags setf
Python built-in descriptor python has some built-in descriptor objects, such as PRoperty, staticmethod, and classmethod. python implementation is as follows:

Python built-in descriptor

Python has some built-in descriptor objects, such as PRoperty, staticmethod, and classmethod. python implementation is as follows:

Class Property (object ):
Def _ init _ (self, getf, setf, delf, doc ):
Self. getf = getf
Self. setf = setf
Self. delf = delf
Self.doc = doc
Def _ get _ (self, instance, own = None ):
If instance is None:
Return self
If self. getf is None:
Raise AttributeError
Return self. getf (instance)
Def _ set _ (self, instance, value ):
If self. setf is None:
Raise AttributeError
Self. setf (instance, value)
Def _ del _ (self, instance ):
If self. delf is None:
Raise AttributeError
Self. delf (instance)
Class StaticMethod (object ):
Def _ init _ (self, func ):
Self. func = func
Def _ get _ (self, instance, own = None ):
Return self. func
Class ClassMethod (object ):
Def _ init _ (self, func ):
Self. func = func
Def _ get _ (self, instance, own = None ):
If own is None:
Own = type (instance)
Def callfunc (* args ):
Return self. func (own, * args)
Return callfunc

Set aliases for attribute values

Sometimes you want to use one property name as the alias of another property name. for example, if you want to set the default value of some properties, it must be the same as the current value of other properties, and you also need to set and delete them independently.

Class DefaultAlias (object ):
Def _ init _ (self, name ):
Self. name = name
Def _ get _ (self, instance, own ):
If instance is None: # class attribute access
Return self
Return getattr (instance, self. name). title ()
Class Person (object ):
Def _ init _ (self, name, aliasname = None ):
Self. name = name
If aliasname is not None:
Self. aliasname = aliasname
Aliasname = DefaultAlias ('name ')
>>> P = Person ('Sam ')
>>> P. aliasname
'Sam'
>>> P. aliasname = 'Jack'
>>> P. aliasname
'Jack'
>>> Del p. aliasname
>>> P. aliasname
'Sam'

In this way, an alias aliasname is set for the attribute name, or the aliasname value is stored in the name. DefaultAlias is not a data descriptor because it does not have the _ set _ method, but rather a non-data descriptor. Therefore, when we assign a value to an instance property (p. aliasname = 'Jack'), the instance will normally record the property, and the instance property will overwrite the class property. In this way, the aliasname attribute can be set separately without affecting the name attribute. When we delete del p. aliasname, the attributes of the instance are deleted and the class attributes are displayed again.

For some developed classes, to maintain compatibility with subsequent versions, you can use a new name to name methods and attributes, while retaining the availability of old names.

Class OldAlias (object ):
Def _ init _ (self, name, oldname ):
Self. name = name
Self. oldname = oldname
Def _ warn (self ):
Print 'use % r, not % R' % (self. name, self. oldname)
Def _ get _ (self, instance, own ):
Self. _ warn ()
If instance is None:
Return self
Return getattr (instance, self. name)
Def _ set _ (self, instance, value ):
Self. _ warn ()
Setattr (instance, self. name, value)
Def _ del _ (self, instance ):
Self. _ warn ()
Delattr (instance, self. name)
Class NewClass (object ):
Def _ init _ (self, newname ):
Self. newname = newname
Oldname = OldAlias ('newname', 'oldname ')
>>> C = NewClass ('A ')
>>> C. oldname
Use 'newname', not 'oldname'
'A'

The old code that uses this class uses the class attribute oldname, and a warning message is printed to encourage users to use the new attribute newname.

Cache property value

Calculate the values of instance attributes or class attributes as needed, and provide automatic cache.

Class CachedAttribute (object ):
Def _ init _ (self, method, name = None ):
Self. method = method
Self. name = name if name else method. _ name __
Def _ get _ (self, instance, own ):
If instance is None:
Return self
Result = self. method (instance)
Setattr (instance, self. name, result)
Return result
Class MyObject (object ):
Def _ init _ (self, n ):
Self. n = n
@ CachedAttribute
Def square (self ):
Return self. n * self. n
>>> M = MyObject (2)
>>> M. square
4
>>> M. n = 5
>>> M. square
4
>>> Del m. square
>>> M. square
25

After the first access to m. square, the square attribute is cached in instance m. When the instance attribute n is changed, the square attribute is not changed. If you need to clear the cache, del m. square. The value of accessing the square attribute again will be calculated again.

Cache class attributes:

Class CachedClassAttribute (CachedAttribute ):
Def _ get _ (self, instance, own ):
Return super (CachedClassAttribute, self). _ get _ (own, own)
Class MyClass (object ):
Class_attr = 24
@ CachedClassAttribute
Def square (cls ):
Return cls. class_attr * cls. class_attr

All such instances have the same cache value:

>>> A = MyClass ()
>>> B = MyClass ()
>>> A. square
>>> Print a. square
576
>>> Print B. square
576
>>> Print MyClass. square
576

The above is the content of the python descriptor (2). For more information, see The PHP Chinese website (www.php1.cn )!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.