custom class

Note that variable or function names of the form __xxx__have special uses in Python. Such as __len__()the method is to allow the class to act on the len()function.

In addition, there are many such special-purpose functions in Python classes that can help us customize classes.

1. String customization __str__

First, put a Person class one by one, and introduce the problem of custom class by outputting an instance

 
 
#Coding = utf- 8

class Person(object):
    def __init__(self,name):
        self.name = name

print Person("rhx")
Output result: <__main__.RoundFloatManual object at 0x00000000056A24E0>

In fact, I originally wanted to output the instantiated object, but how can the output address information be displayed in the form that I want to output?

At this point, you need to use the __str__ method to return a string

#Coding = utf- 8

class Person(object):
    def __init__(self,name):
        self.name = name
    def __str__(self):
        return "Person object (name: %s)" %self.name
    
print Person("rhx")
Output: Person object (name: rhx)

But know that if you don't save the instance object to a variable when you instantiate the object, it will be gone soon and will be reclaimed by the automatic garbage collector, because there is no reference to this instance, so for Person('rhx') When an object is instantiated, if it is not assigned to a variable, a block of memory will be allocated to it when the instance is created, and then it will be released. If you directly call the variable of the instantiated object on the python command line, you will not get the desired output.

>>> class Person(object):
...     def __init__(self,name):
...         self.name = name
...     def __str__(self):
...         return "Person object (name: %s)" %self.name
...
>>> p = Person("rhx")
>>> p
<__main__.Person object at 0x0000000004A829E8>

Note that this is in Python (command line), and the IDE of the first part is pycharm. The output result is also an address value, so how to get the expected result?

This is because the direct display variable is not called __str__() but __repr__(). The difference between the two is that __str__ returns a string visible to the user, while __repr__ returns a string that the developer sees. That is to say, __repr__ is for debugging, that is, when the object is dumped in the interpreter, the default object symbol is displayed, so if you want to fix it, you only need to override __repr__(), a simple way is Copy the implementation code of __str__() to __repr__(), but if there is a problem with the implementation method of __str_, then the bug will also be brought to __repr__. Since everything in python is an object, __str__( ) a reference to this object is assigned to __repr__, so there is:

>>> class Person(object):
...     def __init__(self,name):
...         self.name = name
...     def __str__(self):
...         return "Person object (name: %s)" %self.name
...     __repr__= __str__
...
>>> p = Person("rhx")
>>> p
Person object (name: rhx)

2. Numerical customization __add__

In string customization, meaningful output can be displayed through __str__. How to implement addition to objects in a class?

class Time(object):
    def __init__(self,hr,min):
        self.hour = hr
        self.minute = min

    def __str__(self):
        return '%d:%d' % (self.hour,self.minute)
    __repr__ = __str__

my = Time(10,20)
tue = Time(9,35)
print my
print tue

print my + kill
Output result:
10:20
Traceback (most recent call last):
9:35
  File "F:/py_test/Python Advanced/RoundFloat2.py", line 25, in <module>
    print my + kill
TypeError: unsupported operand type(s) for +: 'Time' and 'Time'

When the object is instantiated, it can be displayed normally, but the addition operation cannot be performed. Therefore, it needs to be overloaded. The overloading is relatively simple, such as +, only the __add__() method needs to be overloaded. How to deal with this total number, because after the addition is a new Time object, there is no mon and tue objects. make modifications, so create a new object and fill in the calculated total

    def __add__(self, other):
        return self.__class__(self.hour+other.hour,self.minute+other.minute)

As in the normal case, the new object is implemented by calling the class, but here is not the Time class, but __class__. In the class, the class name is generally not used directly, but the __class__ attribute of self is used , instantiate the class of self, and call it.

In addition, I also hope to implement "in-situ" operations, such as the form of +=, adding an amount to the original variable, that is, in-situ addition, __iadd__(), to support the addition form of mon += tue, overloading The only secret of a __i*__() method is that it must return self, so it is not difficult to understand that incremental addition is performed on the basis of the original object

    def __iadd__(self, other):
        self.hour += self.hour + other.hour
        self.minute += self.minute + other.minute

3 、 __ iter__

        An iterator is an object that has a next() method, instead of counting by index, when a looping mechanism (such as for...) needs the next item, calling the iterator's next() method can get it, the item After all the acquisitions are completed, a StopIteration exception is raised to tell the external caller that the iteration is complete. For how to create an iterator, you can get its iterator by calling iter() on an object. How to implement in a class

class Fib(object):
    def __init__(self):
        self.a,self.b = 0,1 #The first two items of the Fibonacci sequence
    def __iter__(self):
        return self

    def next(self):
        self.a ,self.b = self.b,self.a + self.b #array iteration
        if self.b >= 5000:
            raise StopIteration
        return self.a
for n in Fib():
    print n

4. Element gets __getitem__

Although the iteration of the Fib class is implemented above, making it look like a list, is it possible to get an element like a list?

print "The second number of Fib: %d" %Fib()[7]
Output result:
    print "The second number of Fib: %d" %Fib()[7]
TypeError: 'Fib' object does not support indexing

Therefore, if you want to access according to the following table like a list, you need to implement the __item__() method

    def __getitem__(self, item):
        a,b = 1,1
        for i in range(item):
            a,b = b,a + b
        return  a
This will allow you to slice




Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325592507&siteId=291194637