Chapter IX category
9.1 creating and using classes
Using classes can simulate almost anything. Let's write a simple class Dog that represents a Dog. It doesn't represent a specific Dog, but any Dog. What do we know about most pet dogs? They all have names and ages. We also know that most dogs squat and roll. Since most puppies have the above two information (name and age) and two behaviors (squatting and rolling), our Dog class will include them. This class lets python know how to create objects that represent puppies. After writing this class, we will use it to create an instance that represents a particular Dog.
9.1.1 create Dog class
Each instance created according to the Dog class will store the name and age. We have given each Dog the ability to squat (sit()) and roll_over():
dog.py
class Dog: """A simple attempt to simulate a dog""" def __init__(self, name, age): """Initialize properties name and age""" self.name = name self.age = age def sit(self): """Simulate a dog sitting down when ordered""" print(f"{self.name} is now sitting.") def roll_over(self): """Simulate a dog rolling when it receives a command""" print(f"{self.name} rolled over!")
There are many things to pay attention to here, but don't worry. This chapter is full of such structures. You have a lot of time to get familiar with it.
Here we first define a class named Dog. By convention, in python, capitalized names refer to classes. There are no parentheses in this class definition because you want to create this class from a blank space. Then a document string is written to describe the functions of this class.
- Method__ init__ ( )
Functions in a class are called methods. Everything you learned about functions earlier applies to methods. At present, the only important difference is the way to call methods. In the above code__ init__ () is a special method. Whenever you create a new instance according to the Dog class, python will run it automatically. In the name of this method, there are two underscores at the beginning and end, which is a convention to avoid name conflicts between Python default methods and ordinary methods. Make sure__ init__ There are two underscores on both sides of (), otherwise when you use a class to create an instance, this method will not be called automatically, resulting in an undetectable error.
We will use the method__ init__ () is defined to contain three formal parameters: self, name, and age. In the definition of this method, the formal parameter self is essential and must precede other formal parameters. Why must the formal parameter self be included in the method definition? Because when Python calls this method to create a Dog class instance, the argument self will be automatically passed in. Each method call associated with an instance automatically passes the argument self, which is a reference to the instance itself, so that the instance can access the properties and methods in the class. When you create a Dog instance, python calls the methods of the Dog class__ init__ ( ). We will pass the name and age to Dog() through the arguments, and self will pass it automatically, so we don't need to pass it. Whenever you create an instance from the Dog class, you only need to provide values for the last two formal parameters (name and age).
Self. In the code Both variables defined at name have the prefix self. Variables prefixed with self are available to all methods in the class and can be accessed through any instance of the class. self.name = name gets the value associated with the formal parameter name and assigns it to the variable name, and then the variable is associated with the currently created instance. self.age = age works similarly. Variables that can be accessed through instances like this are called properties.
The Dog class also defines two other methods: sit () and roll_over( ) . These methods do not require additional information when executed, so they have only one formal parameter, self. The instances we'll create later have access to these methods, in other words, they all squat and roll. Currently, sit() and roll_ What over() does is limited. It just prints a message indicating that the Dog is squatting or rolling. However, these methods can be extended to simulate the actual situation: if this class is included in a computer game, these methods will contain code to create animation effects of Dog squatting and rolling; If this class is used to control the robot Dog, these methods will make the robot Dog squat and roll.
9.1.2 create instances based on classes
Think of a class as a description of how to create an instance. The Dog class is a series of instructions that let python know how to create an instance representing a particular Dog.
Let's create an instance that represents a specific dog:
class Dog: """A simple attempt to simulate a dog""" def __init__(self, name, age): """Initialize properties name and age""" self.name = name self.age = age def sit(self): """Simulate a dog sitting down when ordered""" print(f"{self.name} is now sitting.") def roll_over(self): """Simulate a dog rolling when it receives a command""" print(f"{self.name} rolled over!") my_dog = Dog('Willie',6) print(f"My dog's name is {my_dog.name}.") print(f"My dog is {my_dog.age} years old.")
The Dog class written in the previous example is used here. The code first asks Python to create a Dog named 'Willie' and age 6. When this line of code is encountered, python uses the arguments' Willie 'and 6 to call the method of the Dog class__ init__ ( ). Method__ init__ () create an instance representing a specific Dog and set the properties name and age with the provided values. Next, python returns an instance representing the Dog, and we assign this instance to the variable my_ Dog. Naming conventions are useful here: you can generally think of capitalized names (such as Dog) as referring to classes, and lowercase names (such as my_dog) as referring to instances created from classes.
1. Access properties
To access the properties of an instance, use the period notation. In the above code, the following code is written to access my_ Value of dog attribute name:
my_dog.name
Period notation is commonly used in Python. This syntax demonstrates how Python knows the value of an attribute. Here, python finds the instance my first_ Dog, and then find the attribute name associated with the instance. When this attribute is referenced in the dog class, it uses self name. Use the same method in the code to get the value of the attribute age.
The output is about my_ Summary of dog:
My dog's name is Willie. My dog is 6 years old.
2. Call method
After creating an instance from the Dog class, you can use the period notation to call any method defined in the Dog class. Let the Dog squat and roll:
class Dog: """A simple attempt to simulate a dog""" def __init__(self, name, age): """Initialize properties name and age""" self.name = name self.age = age def sit(self): """Simulate a dog sitting down when ordered""" print(f"{self.name} is now sitting.") def roll_over(self): """Simulate a dog rolling when it receives a command""" print(f"{self.name} rolled over!") my_dog = Dog('Willie',6) my_dog.sit() my_dog.roll_over()
To call a method, specify the name of the instance (in this case my_dog) and the method to call, separated by a period. Encountered code my_ Dog. When sit(), python looks for the method sit() in the class Dog and runs its code. Python interprets code in the same way_ Dog. roll_ over( ).
Willie did as we asked:
Willie is now sitting. Willie rolled over!
This grammar is very useful. If you specify appropriate descriptive names for properties and methods, such as name, age, sit(), and roll_over(), even if it's a code block we've never seen before, we can easily infer what it does.
3. Create multiple instances
Any number of instances can be created according to the class as required. Now create another one named your_dog instance:
class Dog: """A simple attempt to simulate a dog""" def __init__(self, name, age): """Initialize properties name and age""" self.name = name self.age = age def sit(self): """Simulate a dog sitting down when ordered""" print(f"{self.name} is now sitting.") def roll_over(self): """Simulate a dog rolling when it receives a command""" print(f"{self.name} rolled over!") my_dog = Dog('Willie',6) your_dog = Dog('Lucy',3) print(f"My dog's name is {my_dog.name}.") print(f"My dog is {my_dog.age} years old.") my_dog.sit() print(f"\nYour dog's name is {your_dog.name}.") print(f"Your dog is {your_dog.age} years old.") your_dog.sit()
In this example, two puppies named Willie and Lucy are created. Each dog is an independent instance with its own set of properties and can perform the same operations:
My dog's name is Willie. My dog is 6 years old. Willie is now sitting. Your dog's name is Lucy. Your dog is 3 years old. Lucy is now sitting.
Even if the second Dog is given the same name and age, python will still create another instance based on the Dog class. You can create as many instances of a class as you want, provided that each instance is stored in a different variable or occupies a different location in a list or dictionary.
9.2 use classes and instances
You can use classes to simulate many scenes in the real world. After the class is written, you will spend most of your time creating instances based on the class. An important task you need to perform is to modify the properties of the instance. You can modify the properties of an instance directly, or you can write a method to modify it in a specific way.
9.2.1 Car
Let's write a class that represents a car. It stores information about cars and has a way to summarize this information:
car.py
class Car: """A simple attempt to simulate a car""" def __init__(self,make,model,year): """Initializes the properties that describe the car""" self.make = make self.model = model self.year = year def get_descriptive_name(self): """Returns a clean description""" long_name = f"{self.year} {self.make} {self.model}" return long_name.title() my_new_car = Car('audi','a4',2019) print(my_new_car.get_descriptive_name())
First, the method is defined__ init__ ( ). Like the previous Dog class, the first formal parameter of this method is self. The method also contains three other formal parameters: make, model, and year. Method__ init__ () accepts the values of these parameters and assigns them to the properties of the instance created from this class. When creating a new Car instance, you need to specify its manufacturer, model, and year of manufacture.
Subsequently, a named get is defined_ descriptive_ Method of name(). It uses the attributes year, make and model to create a string describing the Car, so that we don't have to print the value of each attribute separately. To access the value of the property in this method, use self make,self.model and self year . Then an instance is created based on the Car class and assigned to the variable my_new_car. Next, call the get method_ descriptive_ Name (), point out what kind of Car we have:
2019 Audi A4
To make this class more interesting, let's add a time-varying attribute to it to store the total mileage of the car.
9.2.2 assigning default values to attributes
When creating an instance, some properties do not need to be defined through formal parameters, but can be defined in the method__ init__ Specify a default value for it in ().
Let's add an object named odometer_ The initial value of the reading property is always 0 We also added a file called read_ The odometer () method is used to read the odometer of the car:
class Car: """A simple attempt to simulate a car""" def __init__(self,make,model,year): """Initializes the properties that describe the car""" self.make = make self.model = model self.year = year self.odometer_reading = 0 def get_descriptive_name(self): """Returns a clean description""" long_name = f"{self.year} {self.make} {self.model}" return long_name.title() def read_odometer(self): """Print a message indicating the car mileage""" print(f"This car has {self.odometer_reading} miles on it.") my_new_car = Car('audi','a4',2019) print(my_new_car.get_descriptive_name()) my_new_car.read_odometer()
Now, when Python calls a method__ init__ () to create a new instance, the manufacturer, model, and year of manufacture are stored in the same way as the previous instance. Next, python will create a named odometer_ And set its initial value to 0 Then we define a file called read_odometer() method, so that you can easily learn the mileage of the car.
At the beginning, the mileage of the car is 0:
2019 Audi A4 This car has 0 miles on it.
There are not many cars with an odometer reading of 0 when they are sold, so we need a way to modify the value of this attribute.
9.2.3 modifying attribute values
We can modify the value of an attribute in three ways: directly through an instance, setting through a method, and incrementing through a method (adding a specific value). These methods are described in turn below.
1. Directly modify the value of the attribute
The easiest way to modify the value of a property is to access it directly through an instance. The following code sets the odometer reading directly to 23:
class Car: """A simple attempt to simulate a car""" def __init__(self,make,model,year): """Initializes the properties that describe the car""" self.make = make self.model = model self.year = year self.odometer_reading = 0 def get_descriptive_name(self): """Returns a clean description""" long_name = f"{self.year} {self.make} {self.model}" return long_name.title() def read_odometer(self): """Print a message indicating the car mileage""" print(f"This car has {self.odometer_reading} miles on it.") my_new_car = Car('audi','a4',2019) print(my_new_car.get_descriptive_name()) my_new_car.odometer_reading = 23 my_new_car.read_odometer()
First, use the period representation to directly access and set the attribute odometer of the car_ reading. This line of code makes python in my instance_ new_ Attribute odometer found in car_ Reading and set its value to 23:
2019 Audi A4 This car has 23 miles on it.
Sometimes you need to access properties directly like this, but other times you need to write methods to update properties.
2. Modify the value of the attribute through the method
If there is a way to update properties for you, it will be of great benefit. This eliminates the need for direct access to the property and allows the value to be passed to the method, which updates internally.
The following example demonstrates an example called update_ Method of odometer():
class Car: --snip-- def update_odometer(self,mileage): """Set the odometer reading to the specified value""" self.odometer_reading = mileage my_new_car = Car('audi','a4',2019) print(my_new_car.get_descriptive_name()) my_new_car.update_odometer(23) my_new_car.read_odometer()
The only change made to the Car class is the addition of the method update_odometer( ). This method accepts a mileage value and assigns it to self odometer_ reading. Then call update_. Odometer (), and provides an argument 23 (the argument corresponds to the formal parameter mileage in the method). It sets the odometer reading to 23 and the method read_odometer() prints this reading:
2019 Audi A4 This car has 23 miles on it.
You can update the method_ Odometer () is extended to do extra work when modifying odometer readings. Let's add some logic to prohibit anyone from callback the odometer reading:
class Car: --snip-- def update_odometer(self,mileage): """ Set the odometer reading to the specified value It is forbidden to callback the odometer reading """ if mileage >= self.odometer_reading: self.odometer_reading = mileage else: print("You can't roll back an odometer!")
Now, update_odometer() checks whether the specified reading is reasonable before modifying the attribute. If the newly specified mileage is greater than or equal to the original mileage (self.odometer_reading), change the odometer reading to the newly specified mileage, otherwise a warning will be issued indicating that the odometer cannot be recalled.
3. Increment the value of the attribute through the method
Sometimes you need to increment the attribute value by a specific amount instead of setting it to a new value. Suppose we buy a used car and add 100 miles from purchase to registration. The following method allows us to pass this increment and increase the odometer reading accordingly:
class Car: --snip-- def update_odometer(self,mileage): --snip-- def increment_odometer(self,miles): """Increase the odometer reading by the specified amount""" self.odometer_reading += miles my_used_car = Car('subaru','outback',2015) print(my_used_car.get_descriptive_name()) my_used_car.update_odometer(23_500) my_used_car.read_odometer() my_used_car.increment_odometer(100) my_used_car.read_odometer()
New method increment_odometer() accepts a number in miles and adds it to self odometer_ Reading. Then create a used car my_used_car . Then call the method update_odometer() and pass in 23_ 500, set the odometer reading of this used car to 23500. Then call increment_. Odometer () and pass in 100 to increase the 100 miles traveled from purchase to registration:
2015 Subaru Outback This car has 23500 miles on it. This car has 23600 miles on it.
You can continue to modify this method to prevent the increment from being negative, so that someone can use it to call back the odometer.
Note: you can use methods similar to the above to control how users modify attribute values (such as odometer readings), but anyone who can access the program can modify the odometer to any value by directly accessing the attribute. To ensure safety, in addition to the basic inspection similar to the previous one, special attention should be paid to details.
9.3 succession
When writing classes, you don't always start with a blank space. If the class you are writing is a special version of another off the shelf class, you can use inheritance. When a class inherits from another class, it will automatically get all the properties and methods of the other class. The original class is called the parent class, and the new class is called the child class. Subclasses inherit all the properties and methods of the parent class, and can also define their own properties and methods.
9.3.1 method of subclass__ init__ ( )
When writing a new class based on an existing class, you usually call the methods of the parent class__ init__ ( ). This will initialize in the parent class__ init__ () method, so that subclasses contain these properties.
For example, let's simulate an electric vehicle. Electric vehicle is a special vehicle, so you can create a new class ElectricCar based on the Car class you created earlier. In this way, you only need to write code for the unique attributes and behaviors of electric vehicles.
Let's create a simple version of the ElectricCar class, which has all the functions of the Car class:
class Car: """A simple attempt to simulate a car""" def __init__(self,make,model,year): self.make = make self.model = model self.year = year self.odometer_reading = 0 def get_descriptive_name(self): long_name = f"{self.year} {self.make} {self.model}" return long_name.title() def read_odometer(self): print(f"This car has {self.odometer_reading} miles on it.") def update_odometer(self,mileage): if mileage >= self.odometer_reading: self.odometer_reading = mileage else: print("You can't roll back an odometer!") def increment_odometer(self,miles): """Increase the odometer reading by the specified amount""" self.odometer_reading += miles class ElectricCar(Car): """The uniqueness of electric vehicles""" def __init__(self,make,model,year): """Initializes the properties of the parent class""" super().__init__(make,model,year) my_tesla = ElectricCar('tesla','model s',2019) print(my_tesla.get_descriptive_name())
The first is the code of the Car class. When creating a subclass, the parent class must be included in the current file and precede the subclass. Then the subclass ElectricCar is defined. When defining a subclass, you must specify the name of the parent class within parentheses. Method__ init__ () accept the information needed to create the Car instance.
The subsequent super() is a special function that allows you to call the methods of the parent class. This line of code makes python call the method of Car class__ init__ (), let the electrocar instance contain all the attributes defined in this method. The parent class is also called a superclass, from which the name super comes.
To test that inheritance works correctly, we tried to create an electric Car, but the information provided is the same as when we created an ordinary Car. Finally, an instance of the ElectricCar class is created and assigned to the variable my_tesla. This line of code calls the method defined in the electrocar class__ init__ (), which makes python call the method defined in the parent class Car__ init__ ( ). We provide arguments' Tesla ',' model s', and 2019.
Except method__ init__ () there are no other unique properties and methods for electric vehicles. At present, we just want to confirm that electric vehicles have the behavior of ordinary vehicles:
2019 Tesla Model S
The behavior of the ElectricCar instance is the same as that of the Car instance. It is now time to define the attributes and methods specific to electric vehicles.
9.3.2 define attributes and methods for subclasses
After allowing one class to inherit from another, you can add new properties and methods required to distinguish the molecular class and parent class.
Next, add an electric vehicle specific attribute (battery) and a method to describe the attribute. We will store the battery capacity and write a method to print the battery Description:
class Car: --snip-- class ElectricCar(Car): """The uniqueness of electric vehicles""" def __init__(self,what,which,when): """ Initializes the properties of the parent class Reinitialize EV specific attributes """ super().__init__(what,which,when) self.battery_size = 75 def describe_battery(self): """Print a message describing the battery capacity""" print(f"This car has a {self.battery_size}--kWh battery.") my_tesla = ElectricCar('tesla','model s',2019) print(my_tesla.get_descriptive_name()) my_tesla.describe_battery()
First, add a new attribute self battery_ Size and set the initial value to 75. All instances created from the electrocar class will contain this attribute, but none of the Car instances will contain it. Subsequently, a named describe was added_ Battery() method to print information about the battery. When calling this method, you will see a unique description of electric vehicle:
2019 Tesla Model S This car has a 75--kWh battery.
There are no restrictions on the specificity of the electrocar class., When simulating an electric vehicle, any number of attributes and methods can be added according to the required accuracy. If an attribute or method is common to any vehicle, but not specific to electric vehicles, it should be added to the Car class instead of the ElectricCar class. In this way, people using the Car class will get the corresponding functions, while the ElectricCar class only contains codes that deal with the unique attributes and behaviors of electric vehicles.
9.3.3 method of overriding parent class
The method of the parent class can be overridden as long as it does not conform to the behavior of the real object simulated by the child class. To do this, define a method in the subclass with the same name as the parent method to override. In this way, python will not consider the parent method, but only focus on the corresponding method you define in the child class.
Suppose the Car class has a file named fill_gas_tank(), which means nothing to all electric vehicles, so you may want to rewrite it. The following demonstrates a rewriting method:
class ElectricCar(Car): --snip-- def fill_gas_tank(self): """Electric cars have no fuel tanks""" print("This car doesn't need a gas tank!")
Now, if someone calls the fill method on an electric vehicle_ gas_ Tank(), python will ignore the method fill in the Car class_ gas_ Tank (), and run the above code instead. Using inheritance allows subclasses to retain the essence inherited from the parent class and eliminate the unnecessary dregs.
9.3.4 using instances as attributes
When using code to simulate the real object, you may find that you add more and more details to the class: the attribute and method lists and files are getting longer and longer. In this case, you may need to extract a part of the class as a separate class. You can split large classes into small classes that work together.
For example, as we continue to add details to the electrocar class, we may find that it contains many attributes and methods specifically for automobile batteries. In this case, these attributes and methods can be extracted and put into a class named Battery, and a Battery instance can be used as the attributes of the electrocar class:
class Car: --snip-- class Battery: """A simple attempt to simulate electric vehicle battery""" def __init__(self,battery_size=75): """Initialize battery properties""" self.battery_size = battery_size def describe_battery(self): """Print a message describing the battery capacity""" print(f"This car has a {self.battery_size}--kWh battery.") class ElectricCar(Car): """The uniqueness of electric vehicles""" def __init__(self,what,which,when): """ Initializes the properties of the parent class Reinitialize EV specific attributes """ super().__init__(what,which,when) self.battery = Battery() my_tesla = ElectricCar('tesla','model s',2019) print(my_tesla.get_descriptive_name()) my_tesla.battery.describe_battery()
First, a new class named battery is defined without inheriting any classes. Its method__ init__ () in addition to self, there is another formal parameter battery_size. This parameter is optional: if no value is provided, the battery capacity will be set to 75. Method describe_battery() is also moved into this class.
In the ElectricCar class, add a file named self Attributes of the Battery. This line of code allows python to create a new Battery instance (the default is 75 because the capacity is not specified) and assign the instance to the attribute self Battery. Whenever method__ init__ () is called, so now each electrocar instance contains an automatically created Battery instance.
We create an electric car and assign it to the variable my_tesla. When describing the battery, you need to use the battery attribute of the electric vehicle:
my_tesla.battery.describe_battery()
This line of code makes python in my instance_ Find the attribute Battery in Tesla and call the method describe on the Battery instance stored in the attribute_ Battery() .
The output is the same as before:
2019 Tesla Model S This car has a 75--kWh battery.
This seems to have done a lot of extra work, but now you can describe the Battery in more detail without causing chaos in the electrocar class. Next, add a method to the Battery class, which reports the mileage of the car according to the Battery capacity:
class Car: --snip-- class Battery: --snip-- def get_range(self): """Print a message indicating the battery range""" if self.battery_size == 75: range = 260 elif self.battery_size == 100: range = 315 print(f"This car can go about {range} miles on a full charge.") class ElectricCar(Car): --snip-- my_tesla = ElectricCar('tesla','model s',2019) print(my_tesla.get_descriptive_name()) my_tesla.battery.describe_battery() my_tesla.battery.get_range()
The output indicates the vehicle's range:
2019 Tesla Model S This car has a 75--kWh battery. This car can go about 260 miles on a full charge.
9.4 import class
9.4.1 importing a single class
Let's create a module that contains only the Car class. This makes us face a subtle naming problem: there is already a named Car in this chapter Py, but this module should also be named Car Py, because it contains the code representing the Car. We will solve the naming problem by storing the Car class in a Car Py, which will overwrite the previously used file Car py . From now on, programs using this module must use more specific file names, such as my_car.py . The following is the module Car Py, which only contains the code of Car class:
car.py
"""A class that can be used to represent cars""" class Car: """A simple attempt to simulate a car""" def __init__(self,make,model,year): self.make = make self.model = model self.year = year self.odometer_reading = 0 def get_descriptive_name(self): long_name = f"{self.year} {self.make} {self.model}" return long_name.title() def read_odometer(self): print(f"This car has {self.odometer_reading} miles on it.") def update_odometer(self,mileage): if mileage >= self.odometer_reading: self.odometer_reading = mileage else: print("You can't roll back an odometer!") def increment_odometer(self,miles): """Increase the odometer reading by the specified amount""" self.odometer_reading += miles
Firstly, it contains a document string to describe the content of the module. You should write a document string for each module you create.
Let's create another file my_car.py, where you import the Car class and create its instance:
my_car.py
from car import Car my_new_car = Car('audi','a4',2019) print(my_new_car.get_descriptive_name()) my_new_car.odometer_reading = 23 my_new_car.read_odometer()
The import statement allows python to open the car module and import the car class. In this way, we can use the car class as if it were defined in this file. The output is the same as before:
2019 Audi A4 This car has 23 miles on it.
Importing classes is an effective programming method. If this program contains the whole Class, how long should it be! By moving this Class into a module and importing it, you can still use all its functions, but the main program file becomes neat and easy to read. It also allows you to store most of your logic in separate files. After making sure that the Class works as you want, you can ignore these files and focus on the high-level logic of the main program.
9.4.2 storing multiple classes in a module
Although there should be some correlation between classes in the same module, any number of classes can be stored in a module as needed. Both Battery class and ElectricCar class can help simulate cars. Next, they are added to the car module Py:
car.py
class Car: --snip-- class Battery: """A simple attempt to simulate electric vehicle battery""" def __init__(self,battery_size=75): """Initialize battery properties""" self.battery_size = battery_size def describe_battery(self): """Print a message describing the battery capacity""" print(f"This car has a {self.battery_size}--kWh battery.") def get_range(self): """Print a message indicating the battery range""" if self.battery_size == 75: range = 260 elif self.battery_size == 100: range = 315 print(f"This car can go about {range} miles on a full charge.") class ElectricCar(Car): """The uniqueness of electric vehicles""" def __init__(self,what,which,when): """ Initializes the properties of the parent class Reinitialize EV specific attributes """ super().__init__(what,which,when) self.battery = Battery()
Now you can create a new one named my_electric_car.py file, import the ElectricCar class, and create an electric vehicle:
from car import ElectricCar my_tesla = ElectricCar('tesla','model s',2019) print(my_tesla.get_descriptive_name()) my_tesla.battery.describe_battery() my_tesla.battery.get_range()
The output is the same as we saw earlier, but most of the logic is hidden in one module:
2019 Tesla Model S This car has a 75--kWh battery. This car can go about 260 miles on a full charge.
9.4.3 importing multiple classes from one module
Any number of classes can be imported into the program file as needed. If you want to create ordinary cars and electric cars in the same program, you need to import both Car class and ElectricCar class:
from car import Car,ElectricCar my_beetle = Car('volkswagen','beetle',2019) print(my_beetle.get_descriptive_name()) my_tesla = ElectricCar('tesla','model s',2019) print(my_tesla.get_descriptive_name())
When importing multiple classes from a module, separate the classes with commas. After importing the necessary classes, you can create any number of instances of each class as needed:
2019 Volkswagen Beetle 2019 Tesla Model S
9.4.4 import the whole module
You can also import the entire module and use the period notation to access the required classes. This import method is simple and the code is easy to read. Because the code that creates the class instance contains the module name, it will not conflict with any name used in the current file.
The following code imports the whole car module and creates an ordinary car and an electric car:
import car my_beetle = car.Car('volkswagen','beetle',2019) print(my_beetle.get_descriptive_name()) my_tesla = car.ElectricCar('tesla','model s',2019) print(my_tesla.get_descriptive_name())
9.4.5 import all classes in the module
To import each class in the module, use the following syntax:
from module_name import*
This import method is not recommended for two reasons. First, if you only look at the import statement at the beginning of the file, you can clearly know which classes the program uses, which will be of great benefit. However, this import method is useless to specify which classes in the module are used. Second, this approach may also lead to confusion about names. If you accidentally import a class with the same name as other things in the program file, it will cause an error that is difficult to diagnose. The reason for this introduction is that although it is not commonly used, it may be seen in the code written by others.
When you need to import many classes from a module, you'd better import the whole module and use module_name.ClassName syntax to access the class. In doing so, although the file does not list all the classes used, you clearly know where the imported modules are used in the program. This also avoids name conflicts that may arise from importing each class in the module.
9.4.6 importing one module into another
Sometimes, you need to spread classes into multiple modules to avoid modules being too large or storing unrelated classes in the same module. When storing classes in multiple modules, you may find that classes in one module depend on classes in another module. In this case, you can import the necessary classes in the previous module.
Next, store the Car class in one module and the ElectricCar class and Battery class in another module. Name the second module electric_car.py, and copy the Battery class and electrocar class into this module:
electric_car.py
"""A set of classes that can be used to represent electric vehicles""" from car importr Car class Battery: --snip-- class ElectricCar(Car): --snip--
The ElectricCar class needs to access its parent class car, so first import the car class into the module. If we forget this line of code, python will throw an error when we try to create an electrocar instance. You also need to update the module car to include only the car class.
You can now import classes separately from each module to create any type of car as needed:
from car import Car from electric_car import ElectricCar my_beetle = Car('volkswagen','beetle',2019) print(my_beetle.get_descriptive_name()) my_tesla = ElectricCar('tesla','model s',2019) print(my_tesla.get_descriptive_name())
9.4.7 using aliases
Chapter 8 said that aliases are useful when using modules to organize project code. When you import a class, you can also specify an alias for it.
For example, to create a large number of electric vehicle instances in the program, you need to input electrocar repeatedly, which is very cumbersome. To avoid this trouble, you can specify an alias for electrocar in the import statement:
from electric_car import ElecrticCar as EC
Now you can use this alias every time you need to create an electric vehicle instance:
my_tesla = EC('tesla','roadster',2019)
9.5 Python standard library
The python standard library is a set of modules, which are included in the python we install. Now that you have a general understanding of the working principle of functions and classes, you can start using modules written by other programmers. You can use any function and class in the standard library, just include a simple import statement at the beginning of the program. Let's take a look at the module random, which is very useful when you simulate many real situations.
An interesting function in this module is randint(). It takes two integers as parameters and randomly returns a function between (including) the two integers. The following shows how to generate a random integer between 1 and 6:
>>>from random import randint >>>randint(1,6) 3
Another useful function in the module random is choice(). It takes a list or tuple as a parameter and randomly returns one of the elements:
>>>from random import choice >>>players = ['charles','martina','florence','eli'] >>>first_up = choice(players) >>>first_up 'florence'
When creating security related applications, do not use the module random, but it can be well used to create many interesting projects.
Note: external modules can also be downloaded from other places.