Python magic method-reflection and incremental operations, python Increment

Source: Internet
Author: User

Python magic method-reflection and incremental operations, python Increment
Reflection operation

What is a reflection operator is actually a reversal of two objects. Let's first look at oneNormalRun character implementation:

class Foo(object):    def __init__(self, x):        self.x = x    def __add__(self, other):        return 'Foo:%s + %s' % (self.x, other.x)class Boo(object):    def __init__(self, x):        self.x = x    def __add__(self, other):        return 'Boo:%s + %s' % (self.x, other.x)a = Foo(123)b = Boo(321)print a + bprint b + a

 

 

In a common addition operation, the _ add _ method on the left of the plus sign is called. The caller is self. Therefore, the result is self on the left and other on the right.

 

The reflection operation actually exchanges the two. The following is an example:

class Foo(object):    def __init__(self, x):        self.x = x    def __radd__(self, other):        return 'Foo:%s + %s' % (self.x, other.x)class Boo(object):    def __init__(self, x):        self.x = x    def __radd__(self, other):        return 'Boo:%s + %s' % (self.x, other.x)a = Foo(123)b = Boo(321)print a + bprint b + a

 

First, the difference is that the + method on the right side is called here. Then it is self on the left, and now it is self on the right.

The summary is as follows:Ordinary operations call the method on the left of the operator, while the reflection operator calls the method on the right. The method that calls the operator is self.

Note the following points:

1. Reflection operations on instances of the same class are not supported:

class Foo(object):    def __init__(self, x):        self.x = x    def __radd__(self, other):        return 'Foo:%s + %s' % (self.x, other.x)a = Foo(123)b = Foo(321)print a + bprint b + a

2. When a class implements _ add _, the priority of the _ radd _ method will be concealed, that is, the priority of _ add _ is higher:

class Foo(object):    def __init__(self, x):        self.x = x    def __radd__(self, other):        return 'Foo:%s + %s' % (self.x, other.x)class Boo(object):    def __init__(self, x):        self.x = x    def __add__(self, other):        return 'Boo add:%s + %s' % (self.x, other.x)    def __radd__(self, other):        return 'Boo radd:%s + %s' % (self.x, other.x)a = Foo(123)b = Boo(321)print a + bprint b + a

 

The logic is as follows:

First a + B, python sees that there is no _ add _ METHOD IN a (ignore _ radd __), go to B and find _ radd _ (instead of _ add __),Because when you look for the right side, reflection operations are required. So we finally got this result..

Then there is B + a. If python sees the _ add _ method in B, it calls it directly regardless of the internal structure of.

 

The basic reflection operation is the same thing. The following is a summary:

  • _ Radd _ (self, other)

  • Reflection Addition

  • _ Rsub _ (self, other)

  • Subtraction of reflection

  • _ Rmul _ (self, other)

  • Reflection Division

  • _ Rfloordiv _ (self, other)

  • Reflection floor division, using the // Operator

  • _ Rdiv _ (self, other)

  • Reflection division, using the/operator.

  • _ Rtruediv _ (self, other)

  • Reflection exclusive. Note that it is valid only when from _ future _ import division

  • _ Rmod _ (self, other)

  • Reflection modulo operation, using the % operator.

  • _ Rdivmod _ (self, other)

  • Divmod () built-in function, called when divmod (other, self.

  • _ Rpow __

  • Returns the multiplication result using the ** operator.

  • _ Rlshift _ (self, other)

  • Shifts the reflection left, using the <operator.

  • _ Rrshift _ (self, other)

  • Right Shift of reflection. Use the> operator.

  • _ Rand _ (self, other)

  • The bitwise AND operator.

  • _ Ror _ (self, other)

  • The bitwise OR, using the | Operator.

  • _ Rxor _ (self, other)

  • Returns an exclusive or. Use the ^ operator.

 

Incremental operations

The so-called incremental operation is actually in the form of x + = 1. The following are several examples:

class Foo(object):    def __init__(self, x):        self.x = x    def __iadd__(self, other):        return 'Foo iadd: %s + %s' % (self.x, other)a = Foo(123)a += 1print a

  HoweverIf the implementation of the two objects is _ iadd __, the situation will be quite different:

class Foo(object):    def __init__(self, x):        self.x = x    def __iadd__(self, other):        return 'Foo iadd: %s + %s' % (self.x, other.x)class Boo(object):    def __init__(self, x):        self.x = x    def __iadd__(self, other):        return 'Boo iadd: %s + %s' % (self.x, other.x)a = Foo(123)b = Boo(321)a += bprint a

It seems normal, but the code is as follows:

a = Foo(123)b = Boo(321)a += bprint ab += aprint b

 

 

The error message shows that str does not have the property 'x', but according to the Code, both objects have the property 'x.

In B + = a, this line is wrong, that is, self is B, and other is. Later I tried it and found that:

Return 'boo iadd: % s + % s' % (self. x, other. x)

Changed:

Return 'boo iadd: % s + % s' % (self. x, other)

The code will not report errors, but the output is as follows:

 

It is strange that other changes to the return value of _ iadd _ in a. That is to say, when a calls the _ iadd _ method, when it is used in other incremental operations, other does not represent the object itself, but the return value of its _ iadd.

  When we return to its essence: x + = 1 => x = x + 1, we can see that x has actually been re-assigned, and the value has been re-assigned as the return value of _ iadd. In our code example, the return value of this method is a string. At the beginning, x is an instance of our class. However, after incremental operations, x becomes the return value of the magic method, that is, the string, so the above error is reported.

So we should pay attention to the change of x's identity when using it, otherwise there will be a lot of unexpected troubles.

 

Summary of incremental methods:

  • _ Iadd _ (self, other)

  • Addition assignment

  • _ Isub _ (self, other)

  • Subtraction assignment.

  • _ Imul _ (self, other)

  • Multiplication assignment

  • _ Ifloordiv _ (self, other)

  • Division assignment, floor division, equivalent to the // = Operator.

  • _ Idiv _ (self, other)

  • Division assignment, equivalent to the/= Operator.

  • _ Itruediv _ (self, other)

  • True Division assignment, note that only whenfrom _ future _ import divisionis is valid.

  • _ Imod _ (self, other)

  • Modulo value assignment, equivalent to the % = Operator.

  • _ Ipow __

  • The multiplication value is equivalent to the ** = Operator.

  • _ Ilshift _ (self, other)

  • Shifts the value left, which is equivalent to the <= Operator.

  • _ Irshift _ (self, other)

  • Shifts the value to the left, which is equivalent to the> = Operator.

  • _ Iand _ (self, other)

  • Equivalent to the & = Operator.

  • _ Ior _ (self, other)

  • Or assign a value, which is equivalent to the | = Operator.

  • _ Ixor _ (self, other)

  • XOR operator, equivalent to the ^ = Operator.

 

Welcome to your discussion.

Reference: click here

 

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.