Python magic methods

Source: Internet
Author: User

Http://www.rafekettler.com/magicmethods.html#conclusion.

1. _ new _ is a static method (_ new _ is a static method ), the first argument to _ new _ must be a class; the remainingarguments are the arguments as seen by the constructor call .) call _ new _ to return the instance object, and then call _ init _ to perform further Initialization on the instance object. For some classes of immutable objects (int, str, tuple ), its _ init _ is invalid. To change its value during initialization, override is required.
_ New _ method. When rewriting _ new _, you still need to call the _ new _ method of the parent class, but we can change the parameters or the returned instance objects later. When the override _ new _ calls the parent class _ new _ method internally, the parent class cannot be passed in as the first parameter; otherwise, the Instance Object of the parent class will be obtained, the new class (A _ new _ method that overrides a base class's _ new _ methodmay call that base class's _ new _ method. the first argument to thebase
Class's _ new _ method call shocould be the class argument to theoverriding _ new _ method, not the base class; if you were to pass inthe base class, you wocould get an instance of the base class ). The description of _ new _ on the official website is very detailed at http://www.python.org/download/releases/2.2/descrintro/?#new= __.

2. _ del _ is equivalent to the Destructor (corresponding to, __new _ and _ init _ is the constructor), but it is not called during del x, it is called when the object is recycled. It mainly serves to deal with some additional cleanup work, such as disabling socket and file descriptor. _ Del _ it is best not to use it, or use it with caution, because it cannot guarantee when _ del _ is executed. The best habit is to manually do the necessary aftercare work. For example, if the connection is no longer needed, you should turn it off and do not hand it over to _ del.

3. magic function used for comparison, __cmp __,__ eq __,__ ne __,__ lt __,__ gt __,__ le __, __ge _ (_ cmp _ returns a negative number/0/Integer Based on </=/>)

4. _ str _ called by the built-in function str (), __repr _ called by the built-in function repr () (the former is mainly for people, and the latter is mainly for machines ); __unicode _ is called by the built-in function unicode (). It is similar to str (), but only returns unicode string.

5. _ hash _ is called by the built-in function hash (). An integer must be returned for quick key comparison in the dictionary. to rewrite the function, _ eq __, a = B will contain hash (a) = hash (B ).

6. _ dir _ is called by the built-in function dir () and returns a list containing all attributes. There is no need to rewrite this function, but it is important to rewrite _ getattr _/_ getattribute _ or dynamically generate attributes.

7. Attribute Access Control. People from other languages complain that python does not have class encapsulation in the true sense (Private attributes cannot be defined, and attributes can be set and obtained at will ). This is not the case. python uses magic methods to encapsulate classes, rather than display methods and fields for modifying classes.

_ Getattr _ (self, name). This method is called when a nonexistent attribute is accessed (not a solution for class encapsulation)
_ Setattr _ (self, name, value), whether or not an attribute already exists, you can use this method to define/set the behavior of an attribute. That is to say, you can customize your own rules to make them play a role when the attributes of the class change (it is indeed a type of encapsulation)
_ Delattr __, which is similar to _ setattr _, except that it deletes an attribute instead of setting an attribute. Infinite recursion may occur in the implementation of _ delattr _ When del self. name is called. Exercise caution.
_ Getattribute _ (self, name), which is not recommended (it is rarely used and difficult to implement without a BUG ), it can only be used for classes of the new style (the latest python version contains classes of the new style ). When AttributeError is explicitly called or _ getattribute _ is returned, __getattr _ is called

def __setattr__(self, name, value):    self.name = value    # since every time an attribute is assigned, __setattr__() is called, this    # is recursion.    # so this really means self.__setattr__('name', value). Since the method    # keeps calling itself, the recursion goes on forever causing a crashdef __setattr__(self, name, value):    self.__dict__[name] = value # assigning to the dict of names in the class    # define custom behavior here    class AccessCounter(object):    '''A class that contains a value and implements an access counter.    The counter increments each time the value is changed.'''    def __init__(self, val):        super(AccessCounter, self).__setattr__('counter', 0)        super(AccessCounter, self).__setattr__('value', val)    def __setattr__(self, name, value):        if name == 'value':            super(AccessCounter, self).__setattr__('counter', self.counter + 1)        # Make this unconditional.        # If you want to prevent other attributes to be set, raise AttributeError(name)        super(AccessCounter, self).__setattr__(name, value)    def __delattr__(self, name):        if name == 'value':            super(AccessCounter, self).__setattr__('counter', self.counter + 1)        super(AccessCounter, self).__delattr__(name)]

8. custom sequence: Use the _ len _ and _ getitem _ methods to customize the variable container, _ len _/_ getitem _/_ setitem _/_ delitem _ must be defined __. If you need to have the property that can be iterated, you also need to define _ iter _ (_ iter _ return iterator, which must comply with the iteration protocol, that is, the _ iter _ and next methods are required for the iterator)

_ Getitem _ (self, key), called when self [key] is used. This method is supported by both the immutable container and the variable container.

_ Setitem _ (self, key, value) is called when self [key] = value is used. This method is supported by variable containers.

_ Delitem _ (self, key), called when del self [key] is used. This method is supported by variable containers.

_ Iter _ (self) returns the iterator of a container. There are many ways to trigger this method call. commonly, the built-in functions iter () and "for x in container: "syntax. The iterator must define method _ inter _ to return itself.

_ Reversed _ (self) is called when the built-in function reversed () is used. A reverse sequence is returned. To achieve this method, the sequence is required (such as tuple and list)

_ Contains _ (self, item). This method is called when "in" and "not in" syntax is used, if this method is not defined, python will iterate this sequence and return True when a target (item) is encountered.

_ Missing _ (self, key), used by the dict subclass. This method is called when the requested key does not exist.

9. reflection, which is rarely used, but if needed, you will find that python provides you with this function.

_ Instancecheck _ (self, instance). This function is called when isinstance (instance, class) is used.

_ Subclasscheck _ (self, subclass). This function is called when issubclass (subclass, class) is used.

10. callable objects, a function in python is also an object

_ Call _ (self, [args...]). This method allows instance objects of a class to be called like functions. X () is equivalent to x. _ call _ (): the parameters are random, but the number of parameters of the instance object must be consistent with that defined in _ call _ when calling the function; if multiple _ call _ methods are defined repeatedly in a class, the last method overwrites the previous one, regardless of the parameter format (python does not include the reloads with the same function name in C ++ in the form of parameters/different return values)

11. Context MANAGER: Context manager. when an object is created in the with syntax, Context manager can set and clean up the object (similar to the contextlib module)

_ Enter _ (self): Before executing a code block controlled by the with syntax, the _ enter _ method of the with wrapped object will be called, the return value of this method is bound to "with syntax target" or "as variable after" in "with syntax.

_ Exit _ (self, exception_type, exception_value, traceback): Call the _ eixt _ method of the object when the with-controlled code block is executed or terminated, this method is used to handle exceptions, execute cleanup, or other things that need to be done after the with code block. If the code block is successfully executed, the values of prediction_type, prediction_value, and traceback are None. Otherwise, you can choose to handle the exception or discard it for the user to process it: if you want to process it, ensure that after the processing is complete, the _ exit _ returns True, if you do not want the exception to be processed by the context manager _ exit _, leave it alone.

class Closer:    '''A context manager to automatically close an object with a close method    in a with statement.'''    def __init__(self, obj):        self.obj = obj    def __enter__(self):        return self.obj # bound to target    def __exit__(self, exception_type, exception_val, trace):        try:           self.obj.close()        except AttributeError: # obj isn't closable           print 'Not closable.'           return True # exception handled successfully           >>> from magicmethods import Closer>>> from ftplib import FTP>>> with Closer(FTP('ftp.somesite.com')) as conn:...     conn.dir()...# output omitted for brevity>>> conn.dir()# long AttributeError message, can't use a connection that's closed>>> with Closer(int(5)) as i:...     i += 1...Not closable.>>> i6

12. Building Descriptor Objects

    __get__(self, instance, owner)    __set__(self, instance, value)    __delete__(self, instance)

Http://onlypython.group.iteye.com/group/wiki/1362-python-39-s-descriptor <descriptor description>

What is descriptor? Simply put, descriptor is an attribute of an object, it only exists in the _ dict _ of the class and has special methods _ get _ (there may be _ set _ and _ delete) however, it has a special feature. To facilitate the reference of such an attribute, we give it a name called descriptor attribute.

Data descriptor and non-data descriptor: they both have the _ get _ and _ set _ methods. Such a descriptor is called data descriptor. If there is only the _ get _ method, it is called non-data descriptor.

Property search policy. For obj. attr (Note: obj can be a class ):

A> If attr is an attribute automatically generated by Python (attributes can be divided into two types, one is automatically generated by Python, such as _ class __,__ hash, the other is our custom, as shown in the preceding hello, name. Classes and instance objects both have the _ dict _ attribute, which stores their custom attributes (for classes, there are other things in it) and find! (The priority is very high !)

B> Find obj. _ class __. _ dict __. if attr exists and is a data descriptor, the result of the _ get _ Method of data descriptor is returned. _ class _ parent class and search for data descriptor in the ancestor class

C> in obj. _ dict _, this step is divided into two situations. The first case is that obj is a common instance. If it is found, it is returned directly and cannot be found. The second case is that obj is a class, which is searched in sequence in obj, its parent class, And the _ dict _ of the ancestor class, if a descriptor is found, the result of the _ get _ method of the descriptor is returned. Otherwise, the attr is returned directly. If not, proceed to the next step.

D> in obj. _ class __. _ dict _. If a descriptor is found, the descriptor must be non-data descriptor. If it is a data descriptor, the second step is to find the result of the _ get _ method of the descriptor. If a common property is found, the property value is directly returned. If not, proceed to the next step.

E> unfortunately, Python cannot stand it at last. In this step, it raise AttributeError

Search policy for attribute values. For obj. attr = value:

A> Find obj. _ class _. _ dict __. if attr exists and is a data descriptor, call the _ set _ method of attr to end. If it does not exist, it will continue to search for the parent class and ancestor class of obj. _ class _. If it finds data descriptor, it will call its _ set _ method. If not found, go to the next step.

B> directly add obj. _ dict _ to obj. _ dict _ ['attr'] = value

13. Copying

_ Copy _ (self): When you call copy. copy () for an instance object, the _ copy _ method call of the instance is triggered. The instance itself is a new instance, but all its data is a reference to the data of the original Instance. Modifying the data of the new instance may change the data of the original Instance.

_ Deepcopy _ (self, memodict = {}). When you call copy. deepcopy () on an instance object, the _ deepcopy _ method call of the instance is triggered. Deep copy: The instance itself and its data are new. Memodict is the cache of previously copied objects. When copying recursive data structures, memodict can optimize copying and prevent endless recursion. When you want to copy a single attribute in depth, call copy. deepcopy () for this attribute and take memodict as the first parameter (if you want to use it, you have to study it in depth ~)

14. Pickling Your Objects

Pickling refers to the serialization of python data structures. It can store and reload an object (mostly used for caching)

Pickling is not a built-in type. It supports any class that complies with the pickle protocol. The pickle protocol consists of four optional methods to customize the pickling behavior (a previous article mentioned the use of two of these methods, http://blog.csdn.net/xiarendeniao/article/details/6774520 item52)

    __getinitargs__(self)    __getnewargs__(self)    __getstate__(self)    __setstate__(self, state)    __reduce__(self)    __reduce_ex__(self)
import timeclass Slate:    '''Class to store a string and a changelog, and forget its value when    pickled.'''    def __init__(self, value):        self.value = value        self.last_change = time.asctime()        self.history = {}    def change(self, new_value):        # Change the value. Commit last value to history        self.history[self.last_change] = self.value        self.value = new_value        self.last_change = time.asctime()    def print_changes(self):        print 'Changelog for Slate object:'        for k, v in self.history.items():            print '%s\t %s' % (k, v)    def __getstate__(self):        # Deliberately do not return self.value or self.last_change.        # We want to have a "blank slate" when we unpickle.        return self.history    def __setstate__(self, state):        # Make self.history = state and last_change and value undefined        self.history = state        self.value, self.last_change = None, None

15. What syntaxes will trigger magic methods?

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.