This article mainly introduces the __init__ () method in Python, the __init__ () method is an important basic knowledge of Python learning, the need for friends can refer to the
The __init__ () method is significant for two reasons. The first reason is that initialization is the most important step in the object lifecycle, and each object must be properly initialized before it works correctly. The second reason is that __init__ () parameter values can take many forms.
Because there are many ways to provide parameter values for __init__ (), there are a number of use cases for object creation, and we can look at a few of them. We want to figure it out as much as possible, so we need to define an initialization to properly describe the problem area.
Before we touch the __init__ () method, we all need to look at the hierarchy of the object class implied in Python in a rough and simple way.
In this chapter, we look at the initialization of simple objects in different forms (for example: Poker). After that, we can also look at more complex objects, like hands objects that contain collections, and players that contain policies and states.
Implied Super class--object
Each Python class implicitly has a superclass: object. It is a very simple class definition that hardly does anything. We can create an instance of object, but we can't do too much with it, because many special methods throw exceptions easily.
When we customize a class, object is a superclass. The following is an example of a class definition that simply inherits the object with the new name:
|1 2||Class X:pass|
The following are some of the interactions with custom classes:
|1 2 3 4||>>> x.__class__ <class ' type ' > >>> x.__class__.__base__ <class ' object ' >|
We can see that the class is an object of the type class, and its base class is objects.
As you can see in each method, we also look at the default behavior inherited from Object. In some cases, the behavior of the superclass special method is what we want. In other cases, we need to override this particular method.
The init () method of the base class object
The base of the object lifecycle is creation, initialization, and destruction. We deferred the advanced special methods of creation and destruction to the later chapters, which are currently focused only on initialization.
The superclass object of all classes has a __init__ () implementation that contains pass by default, and we do not need to implement __init__ (). If it is not implemented, the instance variable is not created after the object is created. In some cases, this default behavior is acceptable.
We always add attributes to an object that is a subclass of the base class object. Consider the following class, which requires two instance variables but does not initialize them:
|1 2 3||Class Rectangle:def Area (self): return self.length * self.width|
The rectangle class has a method that uses two properties to return a value. These properties are not initialized. This is the legal Python code. It can effectively avoid setting properties specifically, although it feels a little odd, but it works.
The following is the interaction of the rectangle class:
|1 2 3 4||>>> r = Rectangle () >>> r.length, r.width = 8 >>> r.area () 104|
Obviously it's legal, but it's also a source of confusion, so that's why we need to avoid it.
In any case, this design gives a lot of flexibility so that sometimes we don't have to set all the properties in the __init__ () method. So far we have gone smoothly. An optional attribute is actually a subclass, but there is no real formal declaration as a subclass. Our creation of polymorphism may in some way cause confusion and the improper use of if statements caused by the coiling. Although uninitialized properties may be useful, they are likely to be a precursor to poor design.
The recommendations in the Zen of Python:
"Explicit is better than implicit." "
A __init__ () method should have the instance variable explicitly.
Flexibility and stupidity are among the first thoughts.
When we feel the need to write like this, we are moving from the edge of flexibility to stupidity:
|1||If ' x ' in self.__dict__:|
|1 2 3||try:self.x except Attributeerror:|
It's time to reconsider the API and add a generic method or attribute. Refactoring is more sensible than adding an if statement.
Implementing Init () in a superclass
We initialize the object by implementing the __init__ () method. When an object is created, Python first creates an empty object and then invokes the __init__ () method for that new object. This method function is typically used to create an instance variable of an object and perform any other one-time processing.
The following is the hierarchy defined by the card class example. We will define the card superclass and three subclasses, which are variants of the card. Two instance variables are set directly by the parameter value, and two variables are evaluated by the initialization method:
|1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16-17||Class Card:def __init__ (self, Rank, suit): Self.suit = Suit Self.rank = Rank Self.hard, Self.soft = self._points () clas S Numbercard (card): Def _points (self): return int (self.rank), int (Self.rank) class Acecard (card): Def _points (self): RET Urn 1, one class Facecard (card): Def _points (self): return 10, 10|
In this example, we extract the __init__ () method to the superclass so that the generic initialization in the card superclass can be applied to three subclasses Numbercard, Acecard, and Facecard.
This is a common polymorphic design. Each subclass provides a unique _points () method implementation. All subclasses have the same signature: they have the same methods and properties. Objects of these three subclasses can be used interchangeably in one application.
If we use simple characters for the suit, we can create the card instance as follows:
|1||cards = [Acecard (' A ', '? '), Numbercard (' 2 ', '? '), Numbercard (' 3 ', '? '),]|
We list some of the cards ' classes, brand values and suits. In the long run, we need more intelligent factory functions to create a card instance; Enumerating 52 cards in this way is tedious and error-prone. Before we touch the factory function, we look at some other problems.
To create an explicit constant using init ()
You can define colors for your cards. At 21, the color is irrelevant, and the simple string is OK.
We use the suit constructor as an example of creating a constant object. In many cases, a small number of objects in our application can be defined by a set of constants. A small number of static objects may be part of implementing a policy pattern or state pattern.
In some cases, we will have a constant object pool created in the initialization or configuration file, or we can create constant objects based on command-line arguments. We will get the details of the initialization design and launch design in the 16th chapter, "Copying by command".
Python does not have a simple formal mechanism to define an immutable object, and we will look at the technology that guarantees immutability in the third chapter, "Property access, method attributes, and descriptors." In this example, it makes sense that the colors are immutable.
Here's a class that we'll use to create four explicit constants:
|1 2 3 4||Class Suit:def __init__ (self, Name, symbol): self.name= name self.symbol= symbol|
The following are constants created from this class:
|1||Club, Diamond, Heart, spade = Suit (' Club ', '? '), Suit (' Diamond ', '? '), Suit (' Heart ', '? '), Suit (' Spade ', '? ')|
Now we can create cards from the code fragment shown below:
|1||cards = [Acecard (' A ', spade), Numbercard (' 2 ', spade), Numbercard (' 3 ', spade),]|
This small example, this method is not a huge improvement for the color code of a single feature. In more complex situations, there are policies or state objects that are created in this way. Reuse from small, static constant objects can make policy or state design patterns more efficient.
We have to admit that in Python these objects are not technically immutable, and that they are mutable. The extra coding that makes these objects truly unchanged may have some benefits.
Invariance is attractive but easy to cause trouble. Sometimes they are adjusted by a mythical "malicious programmer" in their application by modifying constant values. It's very stupid to think about it from the design. These fabulous, malicious programmers will not stop doing this because there is no better way to code in Python. A malicious programmer who accesses the source code and modifies it simply wants to write as easily as possible to modify a constant.
It is best not to struggle long when defining a class of immutable objects. In the third chapter, "Property Access, method properties, and descriptors," We will show how to achieve invariance by providing appropriate diagnostic information in a bug-prone program.