chap9 class for getting started with Python

Posted by drums on Sun, 28 Nov 2021 17:21:10 +0100

Create and use classes

Create Dog class

Each instance created according to the Dog class will store the name and age, and give each Dog the ability to squat (hit ()) and roll_over():

class dog:
    def __init__(self,name,age):
        """Initialize properties name and age"""
        self.name = name
        self.age = age

    def sit(self):
        """"Simulate a dog squatting 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")

First, define a Dog class. According to the Convention, in Python, the capitalized name refers to the class. There are no parentheses in the class definition because the class needs to be created from blank space.

Method__ init__ ()

The functions in the class are called methods. In the name of this method, there are two underscores at the beginning and at the end. This is also a convention to avoid name conflicts between python default methods and ordinary methods.

Will method__ init__ It is defined to contain three formal parameters: self,name and age. When creating a Dog instance, the argument self is automatically passed in. Each method call associated with an instance automatically passes the argument self, which is a reference to the strength itself, so that the instance can access the properties and methods in the class.

Create instances from classes

class Dog:
    def __init__(self,name,age):
        """Initialize properties name and age"""
        self.name = name
        self.age = age

my_dog = Dog('goro',6)

print(f"my dog's name is {my_dog.name}.")
print(f"my dog is {my_dog.age} years old.")

Access properties

To access the properties of an instance, use a period notation, such as the following to access my_ The value of the dog attribute name

my_dog.name

Period notation is commonly used in python. This syntax demonstrates how python knows the value of an attribute. Find the instance first_ Dog, and then find the attribute name associated with the instance

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

class Dog:
    def __init__(self,name,age):
        """Initialize properties name and age"""
        self.name = name
        self.age = age

    def sit(self):
        """"Simulate a dog squatting 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('goro',3)
my_dog.sit()
my_dog.roll_over()

To call a method, specify the name of the instance and the method to call, separated by a period. Encountered code my_ When Dog. Sit(), python looks for the method sit() in the class Dog and runs its code

Output results:

goro is now sitting
goro rolled over

Create multiple instances

You can create any number of instances according to the class as required. Next, create another instance named your_dog:

class Dog:
    --snip--

my_dog = Dog('goro',3)
your_dog = Dog('xina',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()

Using classes and instances

Car class

Let's write a class representing cars. There is a way to store information about cars and summarize information:

class Car:

    def __init__(self,make,model,year):
        self.make = make
        self.model = model
        self.year = year

    def get_descriptive_name(self):
        long_name = f"{self.year} {self.make} {self.model}"
        return long_name.title()

my_new_car = Car('audi','a7',2021)
print(my_new_car.get_descriptive_name())

The first def defines the method _init _ (). Like the previous Dog class, the first formal parameter of this method is self, which also includes three formal parameters: make.model and year. The method _init _definesthe values of these formal parameters and assigns them to the attributes of the instances created according to this class. When creating a new Car instance, you need to specify its manufacturer, model and year.

The second def defines a method called get_descriptive_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 attribute in this method, we use self.make,self.model and self.year.

Finally, create an instance according to the Car class and assign it to the variable my_new_car. Next, call the method get_descriptive_name() to indicate what kind of Car we have.

To make this class more interesting, let's add a time-varying attribute to it to store the total mileage of the car

Assign default values to properties

When creating an instance, some attributes do not need to be defined by formal parameters. You can specify default values for them in the method _init_()

Next, add an attribute called odometer_reading, whose initial value is always 0, and a method called read_odometer() to read the milestones of the car.

class 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.")

my_new_car = Car('audi','a7',2021)
print(my_new_car.get_descriptive_name())
my_new_car.read_odometer()

Modify the value of the property

You can modify the value of an attribute in three ways: directly through an instance, setting through a method, and incrementing (adding a specific value) through a method

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 is to modify the odometer reading to 23:

my_new_car.odometer_reading = 23
my_new_car.read_odometer()

Modify the value of an attribute through the method

Instead of directly accessing the property, the value is passed to the method, which updates it internally

class 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):
        self.odometer_reading = mileage

my_new_car = Car('audi','a7',2021)
print(my_new_car.get_descriptive_name())

my_new_car.update_odometer(23)
my_new_car.read_odometer()

The method update_odometer() is added. This method accepts a mileage value and assigns it to self.odometer_reading. The penultimate line calls update_odometer() and provides arguments. 23. The method read_odometer() prints the reading.

The method update_odometer() can be extended to do some extra work when modifying the odometer reading. The following is to 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, and 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

Increment the value of the attribute by method

class Car:
    def __init__(self,make,model,year):
        self.make = make
        self.model = model
        self.year = year

    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):
        self.odometer_reading = mileage

    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()

The newly added method increment_odometer () receives a number and adds it to self.odometer_reading, then creates a used car my_used_car, calls the method update_odometer() to pass 23500, and then calls increment_odometer() to pass 100 to increase the distance of 100.

2015 Subaru Outback
This car has 23500 miles on it.
This car has 23600 miles on it.

inherit

When writing a class, you don't always start with blank space. If the class you want to write is a special version of another ready-made class, you can inherit. When a class inherits another class, it will automatically obtain 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. A child class inherits all the properties and methods of the parent class, and can also define its own properties and methods method.

Subclass method _init()__

When you write a new class based on an existing class, you usually call the parent class's method _init_ (). This initializes all the properties defined in the parent class's _init_ () method so that the child class contains these properties.

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):
        self.odometer_reading += miles

class ElectricCar(Car):
    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())

When creating a subclass, the parent class must be included in the current file and preceded by the child class. When defining a subclass, the name of the parent class must be specified in parentheses. The method _init_ () accepts the information required to create a Car instance.

super() is a special function that can call the methods of the parent class. It is also called super class.

The penultimate line creates an instance of the electrocar class and assigns it to the variable my_tesla. In this line, the electrocar class calls the defined method _init_ (), which calls the method _init_ () defined in the parent class Car.

Except for the method _iniy _ (), electrocar has no other unique properties and methods.

Define properties 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.
Add a battery attribute below:

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):
        self.odometer_reading += miles

class ElectricCar(Car):
    def __init__(self,make,model,year):
        """Initializes the properties of the parent class"""
        super().__init__(make,model,year)
        self.battery_size = 75

    def describe_battery(self):
        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()

A new attribute self.battery_size is added and the initial value is set to 75. A method of describe_battery() is also added to print information about the battery.

Override the method of the parent class

The method of the parent class can be overridden as long as it does not belong to the behavior of the physical object simulated by the child class. You can define a method in a subclass that has the same name as the parent method you want to override. In this way, python will not consider the parent method, but only focus on the corresponding method defined in the child class.

Suppose the Car class has a file named fill_ gas_ The method of tank () is meaningless to electric vehicles. The following shows a rewriting method:

class ElectricCar(Car):
	--snip--

    def fill_gas_tank(self):
        """There is no mailbox for electric vehicles, except hybrid electric vehicles"""
        print("This car doesn't need a gas tank!")

Use instances as properties

When using code to simulate the real object, you will find that more and more details are added to the class: the attribute and method lists and files are getting longer and longer. In this case, you need to extract a part of the class as an independent class. You can split large classes into small classes that work together.

For example, when constantly adding details to the ElectricCar class, you will find that it contains many attributes and methods specifically for car 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:
    """"Analog battery"""

    def __init__(self,battery_size=75):
        """Initialize battery properties""" 
        self.battery_size = battery_size

    def describe_battery(self):
        print(f"This car has a {self.battery_size}-kWh battery.")

class ElectricCar(Car):
    """The uniqueness of electric vehicles"""

    def __init__(self,make,model,year):
        """initialization"""
        super().__init__(make,model,year)
        self.battery = Battery()

my_tesla = ElectricCar('tesla','model s','2019')

print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()

Define a new class of Battery without inheriting any classes

In the electrocar class, an attribute named self.battery is added to let python create a new battery instance (the default value is 75 because there is no specified capacity) and assign the instance to the attribute self.battery. Whenever method__ init__ () will perform this operation when called, so now each electrocar instance contains an automatically created battery instance.

Add another method to Battery to report 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()

New method get_range() makes a simple comparative analysis

Import class

Store the class in the module and import the required module in the main program

Import a single class

Let's create a module that contains only the Car class.

"""A class that can be used to represent cars"""
class 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 descriptive name"""
        long_name = f"{self.year} {self.make} {self.model}"
        return long_name.title()

    def read_odometer(self):
        """Indicate the mileage of the car"""
        print(f"This car has {self.odometer_reading} miles on it.")

    def update_odometer(self,mileage):
        """Set the odometer reading to the specified value, and 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!")

    def increment_odometer(self,miles):
        """Increase the odometer reading by the specified amount"""
        self.odometer_reading += miles

Let's create another file my_car.py, where you import the car class and create its instance:

from car import Car

my_new_car = Car('audi','a7','2019')
print(my_new_car.get_descriptive_name())

my_new_car.odometer_reading = 23
my_new_car.read_odometer()

Output results:

2019 Audi A7
This car has 23 miles on it.

Storing multiple classes in a module

Store any number of classes in a module as needed. Both Battery class and electrocar class can help. The following are added to the module car.py:

"""A class that can be used to represent cars"""
class 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 descriptive name"""
        long_name = f"{self.year} {self.make} {self.model}"
        return long_name.title()

    def read_odometer(self):
        """Indicate the mileage of the car"""
        print(f"This car has {self.odometer_reading} miles on it.")

    def update_odometer(self,mileage):
        """Set the odometer reading to the specified value, and 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!")

    def increment_odometer(self,miles):
        """Increase the odometer reading by the specified amount"""
        self.odometer_reading += miles

class Battery:
    """"Analog battery"""

    def __init__(self,battery_size=75):
        """Initialize battery properties""" 
        self.battery_size = battery_size

    def describe_battery(self):
        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,make,model,year):
        """initialization"""
        super().__init__(make,model,year)
        self.battery = Battery()

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 before, 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.

Importing multiple classes from a module

Any number of classes can be imported into the program file as needed. If you want to create ordinary and electric 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','roadster',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.

Output results:

2019 Volkswagen Beetle
2019 Tesla Roadster

Import the entire module

Import the whole module, and then use the period representation to access the required classes

import car

my_beetle = car.Car('volkswagen','beetle',2019)
print(my_beetle.get_descriptive_name())

my_tesla = car.ElectricCar('tesla','roadster',2019)
print(my_tesla.get_descriptive_name())

Import the whole car module, and then use the syntax module.name.ClassName to access the required classes

Import all classes in the module

from module_name import * 

This import method is not recommended

Import from one module to another

Sometimes you need to spread classes into multiple modules to avoid modules being too large or storing irrelevant classes in the same module. When you store classes in multiple modules, you will 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 Battery class and ElectricCar class in another module

from car import Car
    
class Battery:
    --snip--

class ElectricCar(Car):
	--snip--

The ElectricCar class can access its parent class Car

Use alias

When importing a class, you can specify an alias
For example, if you input electrocar repeatedly, you can replace it with EC

from electric_car import ElectricCar as EC

You can use this alias whenever you need to create an instance

my_tesla = EC('tesla','model s',2019)

Custom workflow

Make the code structure as simple as possible at the beginning. Mengxin first completes all work in one file as far as possible, and then moves the class to an independent module after confirming that everything can run normally. In the later stage, you need the interaction between modules and files. You can try to store classes in modules at the beginning of the project.

python standard library

The python standard library is a set of modules written by others. You only need to include a simple import statement at the beginning of the program, such as the following two functions: randint() and choice()

from random import randint
print(randint(1,6))
from random import choice
players = ['Barbara','Klee','Dliuc','Jean','Sucrose','Venti','Amber']
first_up = choice(players)
print(first_up)

You can also download external modules from other places, such as later cv2, matplotlib, numpy
Download reference articles

Class coding style

The class name shall adopt hump naming method, that is, the first letter of each letter in the class name shall be capitalized rather than underlined. The instance name and module name are in lowercase and underlined between words.

For each class, a document string should be included immediately after the class definition. This document string needs to briefly describe the functions of the class and follow the format convention adopted when writing the document string of the function. The same is true for each module.

Topics: Python OpenCV Deep Learning