Magic method A few common magic methods that Python has always puzzled me about (on)

Source: Internet
Author: User

Here are just a few of the magic methods that may be commonly used, such as __new__, which is not commonly used for meta-class initialization or __init__, is not introduced by anyone who uses this initialization.

In fact, each magic method is in the internal method of rewriting, and do the same as the adorner behavior. It would be convenient to try to understand each detail decorator before trying to understand the truth.

About __str__ and __repr__:

Directly on the example:

classTest (object):def __init__(Self, World): Self.world= Worlddef __str__(self):return 'World is %s str'%Self.worlddef __repr__(self):return 'World is %s repr'%Self.worldt= Test ('World_big')Printstr (t)PrintRepr (t)

Output

World is World_big str
World is World_big repr

In fact __str__ is equivalent to the STR () method and __repr__ equivalent to the Repr () method. STR is for a better understanding of the string formatting, and repr is to let the machine better understand the string formatting.

In fact, the method of obtaining the return value is also very good test, in our usual use of ipython, when not using print direct output object, usually called is the Repr method, this time rewriting the Repr method can let him easily output what we want to know, rather than a default content.

About __hash__ and __dir__:

In fact, in the actual application of writing so long python, there is no need for these two methods to appear in the place, but in some libraries have seen.

__hash__ is the adorner version of the hash () method, and __dir__ is the adorner version of Dir ().

The code shows __hash__ usage:

classTest (object):def __init__(Self, World): Self.world=WORLDX= Test (' World') P= Test (' World')Printhash (x) = =Hash (p)PrintHash (x.world) = =Hash (P.world)classTest2 (object):def __init__(self, song): Self.song=Songdef __hash__(self):return1241x= Test2 ('Popo') P= Test2 ('Janan')Printx, hash (x)PrintP, hash (p)

Output

False
True
<__main__. Test2 Object at 0x101b0c590> 1241
<__main__. Test2 Object at 0x101b0c4d0> 1241

You can see that the hash () method here always returns a number of type int. Can be used to compare a unique object, such as an object of a different memory is not equivalent, and the same string hash will be equal. Then we modify the behavior of the hash function by modifying the __hash__ method. Let him always return 1241, also can easily do.

Another method is Dir (), and everyone familiar with Python knows that Dir () allows us to see what methods and properties are available for invocation in the current environment. If we use the Dir (object) syntax, we can get the methods and properties owned by an object. The same is true if we define __dir__ ()in the class, we can specify which methods and properties can be found by the Dir () method. The same as I do not post the code here, interested friends can try their own.

About controlling parameter access to __getattr__, __setattr__, __delattr__, __getattribute__:

__getattr__ is called when we try to access a property that does not exist, and it is not called if the property exists.

Take a look at a __getattr__ example:

class Test (object):     def __init__ (Self, World):           = World def __getattr__ (self,    Item):        return  = Test ('world123')print x.world4

Output
World4

Here we do not have the World4 property, and if the property is not found, the normal object that inherits objects will throw Atrributeerror error. But here I changed the behavior of the class when the attribute was not found by __getattr__ Magic method. The parameters of the found property are output.

__setattr__ is the Magic method that is called when the parameter is set, which is equivalent to a hook before the parameter is set. Each method of setting a property cannot be wrapped around this magical method, and only the object that owns the Magic method can set the property. When using this method, pay special attention to not being called by loop.

Let's look at an example:

classTest (object):def __init__(Self, World): Self.world= Worlddef __setattr__(self, Name, value):ifName = ='value': Object.__setattr__(Self, name, value-100)        Else: Object.__setattr__(self, name, value) x= Test (123)PrintX.worldx.value= 200PrintX.value

Output
123
100

Here we first initialize an instance of the test class X, by the __init__ method We can notice that the initialized world parameter is assigned value. Here's Self.world = World statement is doing this thing.

Note that when the world parameter is assigned, it is called to the __setattr__ method. In this example, world is name, and the value of the world behind it is values. I did a behavior rewrite in __setattr__ , and I'm going to judge that the name value is ' value ' for special processing, reducing its value by 100. So the expected results are output.

Why do I say __setattr__ is especially prone to cyclic calls? Because any assignment method will go through this magical method, if you use a similar assignment in your rewrite __setattr__ method, loop back to the __setattr__ method. For example:

 class   Test (object):  def  __init__   (self, world) : Self.world  = world  def  __setattr__   (self, name, value): Self.name  = Valuex  = Test (123  Print  x.world 

Output:
Runtimeerror:maximum recursion depth exceeded

Here we want __setattr__ to perform the default behavior, which is to assign value to name, and the same method in object objects, to do similar things. But here we do not call the parent class __setattr__ method to implement, do such an attempt to get the result is, more than the loop call depth, error. Because here, when the initialization method Self.world = World is executed, the __setattr__ method is called, and the Self.name = value inside the __setattr__ method here calls itself. So it caused a cyclic call. So use this magic method to pay special attention.

The behavior of __delattr__ is very similar to __setattr__ , and it is also important to note the cyclic invocation problem, which is similar to the other, except that the attribute assignment becomes a representation of Del Self.name. Here is a direct example, no longer more than repeat.

 class   Test (object):  def  __init__   (self, world) : Self.world  = world  def  __delattr__   (self, item):  print  "  hahaha del something  Span style= "COLOR: #800000" > "  object.  __delattr__   (self, item) x  = Test (123 del   X.world  print  X.world 

Output:

Hahaha del something
Traceback (most recent):
File "/users/piperck/desktop/py_pra/laplace_pra/practie_01_23/c2.py", line A, in <module>
Print X.world
Attributeerror: ' Test ' object has no attribute ' world '

You can see that after we delete the property, we can't find the property. But when I delete a property, I call __delattr__, and I print a word in it, and I print it before I do it.

The only difference between the __getattribute__ and __getattr__ methods is that we've covered the __getattr__ method to intercept the call only when the property is not found. Then overload or add some other action. But __getattribute__ is even more powerful, and he can intercept all the attributes obtained. So it's easy to come up with the problem of cyclic invocation as we mentioned above. The following example illustrates this problem:

classTest (object):def __init__(Self, World): Self.world= Worlddef __getattribute__(self, item):Print 'get_something:%s'%ItemreturnItemx= Test (123)PrintX.worldPrintX.pp

Output
Get_something:world
World
get_something:pp
pp

As you can see, the__getattribute__ blocks all of the properties, unlike __getattr__ , which only intercepts non-existent properties. So the world value 123, which has already been initialized, is also rewritten as the string world. The non-existent properties are also rewritten as pp.

Maybe I'll write again later, explaining some common protocol.

Reference:

A Guide to Python ' s Magic Methods--Rafe kettler September 4

Magic method A few common magic methods that Python has always puzzled me about (on)

Related Article

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.