In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
The main content of this article is to explain "what is the difference between Python__init__ and _ _ new__". Interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Now let the editor take you to learn "what is the difference between Python__init__ and _ _ new__"!
True and false constructor
If you go to interview for the position of Python engineer, the interviewer asks you, what is the constructor of the class in Python?
You don't think about it, of course it's _ _ init__! If you answer in that way, there is a good chance that you will have no chance with offer. Because _ _ init__ is not a constructor in Python, _ _ new__ is. Isn't it a little confusing, Dorsey (Japanese: why)? Don't we always use the _ _ init__ method as a constructor? Why is there another _ _ new__, if _ _ new__ is the constructor, then why do we never use it when we create classes?
Don't worry, we'll take our time. First of all, let's review the use of _ _ init__, let's write a random piece of code:
Class Student:
Def _ _ init__ (self, name, gender):
Self.name = name
Self.gender = gender
That's how we use it all the time, and there's no question whether it's right or not. But let's change the question: how do we implement the Singleton design pattern in Python? How to realize the factory?
From this point of view, you will find that it is impossible to use only the _ _ init__ function, because _ _ init__ is not a constructor, it is just an initialization method. That is to say, our instance is created before _ _ init__ is called, and _ _ init__ just assigns some values to the instance. If we compare the process of creating an instance to making a cake, the _ _ init__ method is not for baking the cake, but for decorating the cake. So obviously, a cake must be baked before embellishment, so the function of the baked cake is _ _ new__.
_ _ new__ function
Let's take a look at the definition of the function _ _ new__. When we use Python object-oriented, we usually do not ReFactor this function, but use the default constructor provided by Python. The logic of the default constructor of Python looks like this:
Def _ _ new__ (cls, * args, * * kwargs):
Return super (). _ _ new__ (cls, * args, * * kwargs)
You can see from the code that basically nothing is done in the function, but the constructor of the parent class is called intact. The creation logic of classes in Python is hidden here, which is created at one level according to inheritance relationships. According to the logical relationship, we can know that when we create an instance, we actually call the _ _ new__ function to create the instance, and then call _ _ init__ to initialize the instance. We can do a simple experiment:
Class Test:
Def _ new__ (cls):
Print ('_ _ new__')
Return object (). _ _ new__ (cls)
Def _ init__ (self):
Print ('_ _ init__')
When we create the class Test, we can know the order of calls within Python by the order of the output.
Cdn.xitu.io/2020/6/11/172a11972493fe32?w=404&h=80&f=jpeg&s=3669 ">
As a result, it is exactly the same as our guess.
Singleton mode
So what can we do by overloading the _ _ new__ function? It is usually used to accomplish things that _ _ init__ cannot do, such as the singleton pattern mentioned earlier, which can be achieved through the _ _ new__ function. Let's make it simple:
Class SingletonObject:
Def _ _ new__ (cls, * args, * * kwargs):
If not hasattr (SingletonObject, "_ instance"):
SingletonObject._instance = object.__new__ (cls)
Return SingletonObject._instance
Def _ init__ (self):
Pass
Of course, if you use it in a concurrency scenario, you need to add a thread lock to prevent concurrency problems, but the logic is the same.
In addition to implementing some functions, you can also control the creation of instances. Because in Python, _ _ new__ is called first and then _ _ init__, is called, so if None is returned when _ _ new__ is called, the final result is None. With this feature, we can control the creation of classes. For example, if you set a condition, the instance can only be created correctly when the condition is met, otherwise a None will be returned.
For example, if we want to create a class that is an int but cannot have a value of 0, we can use this feature of _ _ new__ to implement:
Class NonZero (int):
Def _ _ new__ (cls, value):
Return super (). _ _ new__ (cls, value) if value! = 0 else None
So when we create it with a value of 0, we get a None instead of an instance.
Factory model
Once we understand the characteristics of the _ _ new__ function, we can use it flexibly. We can use it to implement many other design patterns, such as the famous factory pattern.
The so-called factory pattern is to create different instances according to the value of the parameters through an interface. The logic of the creation process is closed to the outside world, and the user does not have to relate to the logic of the implementation. Just like a factory can produce a variety of parts, users do not care about the production process, just need to tell the type of parts needed. Therefore, it is called factory mode.
For example, let's create a series of game classes:
Class Last_of_us:
Def play (self):
Print ('the Last Of Us is really funny')
Class Uncharted:
Def play (self):
Print ('the Uncharted is really funny')
Class PSGame:
Def play (self):
Print ('PS has many games')
Then at this time, we hope to return different games according to different parameters through an interface. If not through _ _ new__, the logic can only be written as a function instead of object-oriented. By overloading _ _ new__, we can easily get instances of different classes with parameters:
Class GameFactory:
Games = {'last_of_us': Last_Of_us,' uncharted': Uncharted}
Def _ _ new__ (cls, name):
If name in cls.games:
Return cls.games [name] ()
Else:
Return PSGame ()
Uncharted = GameFactory ('uncharted')
Last_of_us = GameFactory ('last_of_us')
At this point, I believe you have a deeper understanding of "what's the difference between Python__init__ and _ _ new__". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.