[python笔记]八.类

一.创建和使用类

1)创建类

eg:

class Dog():
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def sit(self):
        print(self.name.title() + "is now sitting.")
    def roll_over(self):
        print(self.name.title() + " rolled over!")

1.方法__init__() (构造函数)(两侧下划线各有两个)
类中的函数称之为方法,__init__为特殊的方法,每次根据类新建实例时,Python都会自动运行它,该例中定义包含三个形参,self必不可少,且位于所有其他形参之前,通过name和age传递年龄和名字,self会自动传
2.定义另外两个方法,由于不需要额外的信息,因此他们只有一个形参self

2)根据类创建实例

eg:

class Dog():
    def __init__(self, name, age):
        self.name = name
        self.age = age
        #super().__init__()
    def sit(self):
        print(self.name.title() + "is now sitting.")
    def roll_over(self):
        print(self.name.title() + " rolled over!")
my_dog = Dog('willie', 6)
print("My dog's name is " + my_dog.name.title() + ".")
print("My dog is " + str(my_dog.age) + " years old.")
my_dog.sit()
my_dog.roll_over()

输出:

My dog's name is Willie.
My dog is 6 years old.
Willieis now sitting.
Willie rolled over!

python使用实参’willie’和6调用Dog类中的方法,__init()__创建一个表示特定小狗的示例,并根据提供的值设置属性name()和age()
__init()__并未显示的包含return语句,python会自动返回一个表示特定小狗的实例存储在变量my_dog中
使用句点表示法访问属性my_dog.name.title()
使用句点表示法调用方法my_dog.roll_over()

3)创建多个实例

可以根据需求创建任意数量的实例。
eg:

class Dog():
    def __init__(self, name, age):
        self.name = name
        self.age = age
        #super().__init__()
    def sit(self):
        print(self.name.title() + " is now sitting.")
    def roll_over(self):
        print(self.name.title() + " rolled over!")
my_dog = Dog('willie', 6)
your_dog = Dog('lucy', 3)
print("My dog's name is " + my_dog.name.title() + ".")
print("My dog is " + str(my_dog.age) + " years old.")
my_dog.sit()
print("Your dog's name is " + your_dog.name.title() + ".")
print("Your dog is " + str(your_dog.age) + " years old.")
your_dog.roll_over()

输出

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 rolled over!

二.使用类和实例

类编写好后,大部分时间都花在使用根据类创建的实例上,需要执行的一个重要任务就是修改实例的属性,可以直接修改实例的属性,也可以编写方法以特定的方式进行修改

1)Car类

eg1:

class Car():
    '''一次模拟汽车的简单尝试'''
    def __init__(self, make, model, year):
        '''初始化汽车的属性'''
        self.make = make
        self.model = model
        self.year = year
    def get_descriptive_name(self):
        '''返回简单的描述信息'''
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()
my_new_car = Car('audi', 'a4', '2016')
print(my_new_car.get_descriptive_name())

输出:

2016 Audi A4

2)给属性指定默认值

类中的每个属性都必须有初始值,哪怕这个值时0或是空字符串,在有些情况下,如设置成默认值时,在方法__init()__中可以指定初始值,如果指定了初始值,那么就无需包含为它提供初始值的形参
如在上例中加上一个名为odometer_reading的属性,初值为0,再添加一个read_odometer()的方法,用于读取汽车的里程表
eg2:

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 = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()
    def read_odometer(self):
        '''打印汽车里程的消息'''
        print("This car has " + str(self.odometer_reading) + " mile on it.")
my_new_car = Car('audi', 'a4', '2016')
print(my_new_car.get_descriptive_name())
my_new_car.read_odometer()

输出:

2016 Audi A4
This car has 12 mile on it.

3)修改属性的值

1.直接修改属性的值通过实例直接访问它
eg:

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 = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()
    def read_odometer(self):
        '''打印汽车里程的消息'''
        print("This car has " + str(self.odometer_reading) + " mile on it.")
my_new_car = Car('audi', 'a4', '2016')
print(my_new_car.get_descriptive_name())
my_new_car.odometer_reading = 20#直接访问修改属性的值
my_new_car.read_odometer()

输出

2016 Audi A4
This car has 20 mile on it.

2.通过方法修改属性的值
在类的内部定义方法,无需直接访问属性,可以将值传递给一个方法,由它在内部更新

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 = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()
    def read_odometer(self):
        '''打印汽车里程的消息'''
        print("This car has " + str(self.odometer_reading) + " mile 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")
my_new_car = Car('audi', 'a4', '2016')
print(my_new_car.get_descriptive_name())
my_new_car.update_odometer(20)
my_new_car.read_odometer()

输出

2016 Audi A4
This car has 20 mile on it.

3.通过方法对属性的值进行递增

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 = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()
    def read_odometer(self):
        '''打印汽车里程的消息'''
        print("This car has " + str(self.odometer_reading) + " mile on it.")
    def increment_oddmeter(self, miles):
        '''将里程表读数增加指定的量'''
        self.odometer_reading += miles
my_new_car = Car('audi', 'a4', '2016')
print(my_new_car.get_descriptive_name())
my_new_car.increment_oddmeter(23500)
my_new_car.read_odometer()
my_new_car.increment_oddmeter(100)
my_new_car.read_odometer()

输出:

2016 Audi A4
This car has 23500 mile on it.
This car has 23600 mile on it.

三.继承

编写类时,并非总是要从空白开始。如果你编写的类时另一个线程的类的特殊版本,可以使用继承

1)子类的方法__init()__

创建子类实例时,python首先要做的就是给父类的所有属性赋值。
eg:

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 = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()
    def read_odometer(self):
        '''打印汽车里程的消息'''
        print("This car has " + str(self.odometer_reading) + " mile 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_oddmeter(self, miles):
        '''将里程表读数增加指定的量'''
        self.odometer_reading += miles
class Electric(Car):
    '''电动汽车的独特之处'''
    def __init__(self, make, model, year):
        '''初始化父类属性'''
        super().__init__(make, model, year)
my_tesla = Electric('tesla', 'model s', '2016')
print(my_tesla.get_descriptive_name())

输出

2016 Tesla Model S

创建子类时,class Electric(Car):父类必须包含在当前文件,此例中Car即为子类.
方法__init__()接受创建Car实例所需的信息
super()函数帮助python将父类与子类联合起来因为父类称为超类(superclass),super因此得名

super().__init__(make, model, year)#这里的super().__init()__()函数里没有self,只有父类函数中需要初始化的属性

这行代码让Python调用ElectricCar的父类的方法__init__()
子类实例化时调用自己的构造函数,该函数又调用父类的构造函数。

2)给子类定义属性与方法

eg:
在上例中添加一个Electric类特有的属性以及Electric类中特有的方法。

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 = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()
    def read_odometer(self):
        '''打印汽车里程的消息'''
        print("This car has " + str(self.odometer_reading) + " mile 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_oddmeter(self, miles):
        '''将里程表读数增加指定的量'''
        self.odometer_reading += miles
class Electric(Car):
    '''电动汽车的独特之处'''
    def __init__(self, make, model, year):
        '''初始化父类属性'''
        super().__init__(make, model, year)
        self.battery_size = 70#初始化电动汽车的特有属性
    def describe_battery(self):
        print("This car has a " + str(self.battery_size) + "-kWh battery.")
my_tesla = Electric('tesla', 'model s', '2016')
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()

输出:

2016 Tesla Model S
This car has a 70-kWh battery.

如果子类中也有需要初始化的属性
eg:

class Restaurant():
    def __init__(self, restaurant_name, cuisine_type, number_served = 0):
        self.restaurant_name = restaurant_name
        self.cuisine_type = cuisine_type
        self.number_served = number_served
class IceCreamStand(Restaurant):
    def __init__(self, restaurant_name, cuisine_type, flavors):
        super().__init__(restaurant_name, cuisine_type)
        self.flavors = flavors
    def show_flavors(self):
        print(self.flavors)
icecreamstand = IceCreamStand('KFC','fired chicken',['red', 'yellow', 'green'])
icecreamstand.show_flavors()

输出

['red', 'yellow', 'green']

其中flavors做为子类的属性在子类的构造函数中初始化
编写子类构造函数需要将父类需要初始化的函数也传进来,调用super().__inti__()函数初始化

3)重写父类的方法

对于父类的方法,只要它不符合子类模拟实物的方法,都可以对其进行重写。为此可以在类中定义一个这样的方法,即它与要重写的父类方法同名,这样,Python不会考虑这个父类方法,只关注在子类中定义的相应方法。
子类的实例化对象调用该方法以子类中定义的为准,不考虑父类的定义。
eg:

class Car():
    '''一次模拟汽车的简单尝试'''
    def __init__(self, make, model, year):
        '''初始化汽车的属性'''
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0#给出默认值的属性,在实例化的时候就不需要传参数了
    def fill_gas_tank(self):
        print("1000")
class Electric(Car):
    '''电动汽车的独特之处'''
    def __init__(self, make, model, year):
        '''初始化父类属性'''
        super().__init__(make, model, year)
        self.battery_size = 70#初始化电动汽车的特有属性
    def fill_gas_tank(self):#重写父类的方法
        print("This car doesn't have a gas tank!")
my_tesla = Electric('tesla', 'model s', '2016')
my_tesla.fill_gas_tank()#调用重写的方法

输出:

This car doesn't have a gas tank!

此时会执行子类中的fill_gas_tank()方法,而不是父类中的fill_gas_tank()方法

4)将实例用作属性

使用代码模拟实物时,类添加的细节越来越多,可以将类的一部分作为一个独立的类提取出来,将大类拆分成多个协同工作的小类。
eg:上例中可以将针对汽车电瓶的属性和方法,提取出来,放在一个Battery的类中,并将一个battery实例作为Electric类的一个属性

eg:

#car类不变,同上例
class Battery():#将battery单独作为一个类
    def __init__(self, battery_size = 70):
        self.battery_size = battery_size
    '''
    def __init__(self):
    	这样的写法同上,将默认值卸载函数体里
        self.battery_size = 70
    '''
    def describe_battery(self):
        print("This car has a " + str(self.battery_size) + "-kWh battery")
    def get_range(self):
        '''打印续航里程'''
        if self.battery_size == 70:
            range = 240
        elif self.battery_size == 85:
            range = 270
        message = "This car can go approximately " + str(range) + "miles on a full charge"
        print(message)
class Electric(Car):
    '''电动汽车的独特之处'''
    def __init__(self, make, model, year):
        '''初始化父类属性'''
        super().__init__(make, model, year)#继承父类
        self.battery = Battery()#将Battery实例化一个对象作为Electric的一个属性
    def fill_gas_tank(self):#重写父类的方法
        print("This car doesn't have a gas tank!")
my_tesla = Electric('tesla', 'model s', '2016')
#my_tesla.fill_gas_tank()#调用重写的方法
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()
my_tesla.battery.get_range()

输出

2016 Tesla Model S
This car has a 70-kWh battery
This car can go approximately 240miles on a full charge

代码self.battery = Battery()将Battery实例化为Electric类下的一个属性,(与从父类继承来的属性与自己定义的属性性质一样)该属性可以去调用Battery类中的两个方法,并且如果不给出初始值,self.battery.battery_size会被初始化为70

四.导入类

随着不断给类添加功能,文件可能变得很长,遵循python的总体理念,应该让文件尽可能整洁,python允许将类存储在模块中,然后再主程序中导入

1)导入单个类

eg:

#car.py
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 = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()
    def read_odometer(self):
        '''打印汽车里程的消息'''
        print("This car has " + str(self.odometer_reading) + " mile 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_oddmeter(self, miles):
        '''将里程表读数增加指定的量'''
        self.odometer_reading += miles
    def fill_gas_tank(self):
        print("1000")
#mycar.py
from car import Car
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
my_new_car.odometer_reading = 23
my_new_car.read_odometer()

输出

2016 Audi A4
This car has 23 mile on it.

在mycar.py文件中使用from car import Car打开模块car并导入Car类,就可以使用了

2)在一个模块中存储多个类

eg:

#car.py
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 = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()
    def read_odometer(self):
        '''打印汽车里程的消息'''
        print("This car has " + str(self.odometer_reading) + " mile 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_oddmeter(self, miles):
        '''将里程表读数增加指定的量'''
        self.odometer_reading += miles
    def fill_gas_tank(self):
        print("1000")
class Battery():
    def __init__(self):
        self.battery_size = 70
    def describe_battery(self):
        print("This car has a " + str(self.battery_size) + "-kWh battery")
    def get_range(self):
        '''打印续航里程'''
        if self.battery_size == 70:
            range = 240
        elif self.battery_size == 85:
            range = 270
        message = "This car can go approximately " + str(range) + " miles on a full charge"
        print(message)
    def upgrade_bettery(self):
        if self.battery_size != 85:
            self.battery_size = 85
class Electric(Car):
    '''电动汽车的独特之处'''
    def __init__(self, make, model, year):
        '''初始化父类属性'''
        super().__init__(make, model, year)#继承父类
        self.battery = Battery()#将Battery实例化一个对象作为Electric的一个属性
    def fill_gas_tank(self):#重写父类的方法
        print("This car doesn't have a gas tank!")
#my_electric.py
from car import Electric#从car.py中导入Electric类
my_tesla = Electric('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()
my_tesla.battery.get_range()

输出

2016 Tesla Model S
This car has a 70-kWh battery
This car can go approximately 240 miles on a full charge

3)从一个模块中导入多个类

car.py同上

#my_car.py
from car import Car,Electric#从car.py中导入Car和Electric两个类
my_beetle = Car('volkswagen', 'bettle', 2016)#Car的实例化
print(my_beetle.get_descriptive_name())
my_tesla = Electric('tesla', 'roadster', 2016)#Electric的实例化
print(my_tesla.get_descriptive_name())

输出

2016 Volkswagen Bettle
2016 Tesla Roadster

4)导入整个模块

#my_car.py
import car#导入整个模块
my_beetle = car.Car('volkswagen', 'bettle', 2016)
print(my_beetle.get_descriptive_name())
my_tesla = car.Electric('tesla', 'roadster', 2016)
print(my_tesla.get_descriptive_name())

输出

2016 Volkswagen Bettle
2016 Tesla Roadster

5)导入模块中的所有类

from module_name import*

不推荐使用,容易混淆或者引发冲突
如果需要导入一个模块中的很多类,最好导入整个模块,并使用moudle_name.class_name来访问类,这样可以清楚的知道那些地方使用了导入的模块,避免了导入模块中的每个类可能引发的名称冲突。

6)在一个模块中导入另一个模块

#car.py
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 = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()
    def read_odometer(self):
        '''打印汽车里程的消息'''
        print("This car has " + str(self.odometer_reading) + " mile 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_oddmeter(self, miles):
        '''将里程表读数增加指定的量'''
        self.odometer_reading += miles
    def fill_gas_tank(self):
        print("1000")
#electric.py
from car import Car
class Battery():
    def __init__(self):
        self.battery_size = 70
    def describe_battery(self):
        print("This car has a " + str(self.battery_size) + "-kWh battery")
    def get_range(self):
        '''打印续航里程'''
        if self.battery_size == 70:
            range = 240
        elif self.battery_size == 85:
            range = 270
        message = "This car can go approximately " + str(range) + " miles on a full charge"
        print(message)
    def upgrade_bettery(self):
        if self.battery_size != 85:
            self.battery_size = 85
class Electric(Car):
    '''电动汽车的独特之处'''
    def __init__(self, make, model, year):
        '''初始化父类属性'''
        super().__init__(make, model, year)#继承父类
        self.battery = Battery()#将Battery实例化一个对象作为Electric的一个属性
    def fill_gas_tank(self):#重写父类的方法
        print("This car doesn't have a gas tank!")
#my car.py
from car import Car
from electric_car import Electric
my_beetle = Car('volkswagen', 'bettle', 2016)
print(my_beetle.get_descriptive_name())
my_tesla = Electric('tesla', 'roadster', 2016)
print(my_tesla.get_descriptive_name())

输出:

2016 Volkswagen Bettle
2016 Tesla Roadster

五.Python标准库

Python标准库是一组模块,安装的python都包括它,可以使用标准库中任何的函数和类,只需要在函数开始包含一条简单的import语句。

六.类编码风格

1.类名使用驼峰命名法,类名中的每个单词首字母都大写,不使用下划线,实例名与模块名都小写,单词之间加上下划线。
2.每个类,在类定义后面包含一个文档字符串,简要的描述类的作用,每个模块包含一个文档字符串,对其中的类做什么进行描述。
3.在类中,使用一个空行来分隔方法,模块中,使用两个空行来分割类。
4.需要同时导入标准库和自己编写的模块,先编写导入标准库的import语句,再添加一个空行,然后编写导入自己的模块的import语句。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值