面向对象编程中,可以编写表示现实世界中的事物或情景的类,并基于类创建对象。编写类时,会定义一大类对象都有的通用行为。基于类创建对象(实例化),每个对象都自动具备这种通用行为,然后可以根据需求赋予每个对象独特的个性。
目录
1.创建和使用类
- 创建Dog类
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()+" is now rolling.")
Python中首字母大写的名称指类。类定义中的括号是空的,因为我们要从空白创建该类。
类中的函数叫方法。__init__()是一个特殊的方法,每当根据类创建实例时,会自动运行。init前后各两个下划线,避免与普通方法冲突。
__init__()中可以包含若干形参,self必不可少且必须位于其他形参之前。类中其他方法第一个形参也是self。
Python调用__init__()创建实例时,会自动传入实参self(不需要手动传),每个与类相关联的方法调用都自动传入实参self,它是一个指向实例自身的引用,让实例可以访问类中的属性和方法。
以self为前缀的变量可供类中所有方法使用,还可以通过类的任何实例来访问这些变量。
- 根据类创建实例
my_dog = Dog('alice',16)
print(my_dog.name)
print(my_dog.age)
创建一个名字为alice,年龄为16的狗。Python使用实参alice和16调用Dog类中的__init__()方法创建一个特定的小狗实例,并使用我们提供的实参设置属性name和age,并将该实例返回存储在my_dog中。
访问实例的属性需要使用句点表示法,my_dog.name 。 Python先找到实例my_dog,再查找与这个实例相关联的属性name。在Dog类中引用这个属性,使用self.name。
类创建实例后,可以使用句点表示法,调用类中的任何方法。my_dog.sit():
my_dog.sit()
my_dog.roll_over()
可以创建多个实例:
my_dog = Dog('alice',16)
print(my_dog.name)
print(my_dog.age)
my_dog.sit()
my_dog.roll_over()
print("----------------")
your_dog = Dog('bob',4)
print(your_dog.name)
print(your_dog.age)
your_dog.sit()
your_dog.roll_over()
2.使用类和实例
根据类创建实例后,一个重要的任务就是修改实例的属性。可以直接修改实例的属性,也可以编写方法以特定的方式进行修改。
- Car 类
class Car():
def __init__(self,make,model,year):
'''车的属性 生产商、型号和生产年份'''
self.make = make
self.model = model
self.year = year
def get_description(self):
'''得到汽车的完整描述'''
#类中调用属性 使用self.
long_name = str(self.make)+' '+str(self.model)+' '+str(self.year)
return long_name.title()
my_car = Car('audi','a4',2016)
print(my_car.get_description())
- 给属性指定默认值
类中每个属性都必须有初始值,如果在__init__()中指定某个属性是默认属性,创建实例时,就无需为他提供初始值的形参。
class Car():
def __init__(self,make,model,year):
'''车的属性 生产商、型号和生产年份'''
self.make = make
self.model = model
self.year = year
self.odometer = 0 #默认属性 默认值为0 表示汽车的里程表
def get_description(self):
'''得到汽车的完整描述'''
#类中调用属性 使用self.
long_name = str(self.make)+' '+str(self.model)+' '+str(self.year)
return long_name.title()
def get_odometer(self):
'''读取汽车的里程数据'''
print('this car has '+str(self.odometer)+' on it.')
my_car = Car('audi','a4',2016) #无需给默认属性odometer提供值
print(my_car.get_description())
my_car.get_odometer()
- 修改属性值
1.直接修改属性值
想直接用实例访问属性那样修改他
my_car.odometer = 23
my_car.get_odometer()
2.用方法来修改属性值
无需直接访问属性,可将值传给方法,在类内部对属性进行更新:
class Car():
def __init__(self,make,model,year):
'''车的属性 生产商、型号和生产年份'''
self.make = make
self.model = model
self.year = year
self.odometer = 0 #默认属性 默认值为0 表示汽车的里程表
def get_description(self):
'''得到汽车的完整描述'''
#类中调用属性 使用self.
long_name = str(self.make)+' '+str(self.model)+' '+str(self.year)
return long_name.title()
def get_odometer(self):
'''读取汽车的里程数据'''
print('this car has '+str(self.odometer)+' on it.')
def set_odometer(self,milege):
'''修改汽车里程数据'''
if milege >= self.odometer:
self.odometer = milege
else:
print("不能回调")
my_car = Car('audi','a4',2016)
my_car.set_odometer(60)
my_car.get_odometer()
- 通过方法对属性值进行递增
有时需要把属性值增加特定的量,而不是设置为全新的值。
class Car():
def __init__(self,make,model,year):
'''车的属性 生产商、型号和生产年份'''
self.make = make
self.model = model
self.year = year
self.odometer = 0 #默认属性 默认值为0 表示汽车的里程表
def get_description(self):
'''得到汽车的完整描述'''
#类中调用属性 使用self.
long_name = str(self.make)+' '+str(self.model)+' '+str(self.year)
return long_name.title()
def get_odometer(self):
'''读取汽车的里程数据'''
print('this car has '+str(self.odometer)+' on it.')
def set_odometer(self,milege):
'''修改汽车里程数据'''
if milege >= self.odometer:
self.odometer = milege
else:
print("不能回调")
def incre_odometer(self,mile):
self.odometer += mile
my_car = Car('audi','a4',2016)
my_car.set_odometer(60)
my_car.get_odometer()
print("------------------")
my_used_car = Car('benz','c180',2018)
my_used_car.set_odometer(20000)
my_used_car.incre_odometer(200)
my_used_car.get_odometer()
3.继承
编写类不总是从空白开始。如果要编写的类是另一个类的特殊版本,可以使用继承。
一个类继承另一个类,将自动获得另一个类的所有属性和方法;被继承的类为父类,新类为子类,子类继承父类所有的属性和方法,同时可以定义自己的属性和方法。
- 子类的__init__()方法
创建子类实例时,首先需要对父类的所有属性进行赋值。
接下里创建一个电动汽车类,为汽车类的子类:
class EletricCar(Car):
def __init__(self,make,model,year):
'''初始化父类属性'''
super().__init__(make,model,year)
my_tesla = EletricCar('tesla','model_s','2018')
my_tesla.get_description()
创建子类时,父类必须在当前文件中,且在子类前面。定义子类时,括号内必须指定父类名称。
super()函数可以调用父类中的方法。
ElectricCar实例的属性和方法和Car的实例一样,具有Car的通用属性和方法。接下来定义电动汽车特有的方法和属性。
- 定义子类特有的属性和方法
class EletricCar(Car):
def __init__(self,make,model,year,battey_size):
'''先初始化父类属性,再初始化子类特有的属性'''
super().__init__(make,model,year)
self.battey_size = battey_size
def get_battey(self):
'''子类特有方法,查看电池大小'''
print("this car has a "+str(self.battey_size)+" battey.")
my_tesla = EletricCar('tesla','model_s','2018',70)
my_tesla.get_battey()
可以对子类添加任意数量的特有属性和方法。
- 重写父类的方法
对于父类的任何方法,只要他不符合子类的行为,都可以进行重写。
子类要重写的方法必须和父类同名。
如果用子类的实例调用重写方法,则调用的是子类中的方法,而不是父类,相当于子类把与父类同名的方法覆盖了。
class Car():
def __init__(self,make,model,year):
'''车的属性 生产商、型号和生产年份'''
self.make = make
self.model = model
self.year = year
self.odometer = 0 #默认属性 默认值为0 表示汽车的里程表
def get_description(self):
'''得到汽车的完整描述'''
#类中调用属性 使用self.
long_name = str(self.make)+' '+str(self.model)+' '+str(self.year)
return long_name.title()
def get_odometer(self):
'''读取汽车的里程数据'''
print('this car has '+str(self.odometer)+' on it.')
def set_odometer(self,milege):
'''修改汽车里程数据'''
if milege >= self.odometer:
self.odometer = milege
else:
print("不能回调")
def incre_odometer(self,mile):
self.odometer += mile
def fill_gas_tank(self):
'''加油'''
print("this car need gas!")
class EletricCar(Car):
def __init__(self,make,model,year,battey_size):
'''先初始化父类属性,再初始化子类特有的属性'''
super().__init__(make,model,year)
self.battey_size = battey_size
def get_battey(self):
'''子类特有方法,查看电池大小'''
print("this car has a "+str(self.battey_size)+" battey.")
def fill_gas_tank(self):
'''电动车没有油箱 对该方法进行重写'''
print("Ele car no gas tank!!!")
my_tesla = EletricCar('tesla','model_s','2018',70)
my_tesla.fill_gas_tank()
- 将实例用作属性
用代码模拟实物时,会发现类的细节越来越多,属性和方法越来越多。
这时可以把类的一部分作为一个独立的类提取出来,将大类拆分为多个协同工作的小类。
比如,给电动汽车添加细节时,我们会发现其中包含很多针对汽车电瓶的属性和方法,可以把这些属性和方法提取出来,放到另一个Battery()类中,并将Battery()的实例用作ElectricCar的一个属性:
class Battery():
def __init__(self,battery_size=70): #设置为默认值 可以不用传
self.battery_size = battery_size
def describe_battery(self):
print("this car has a "+str(self.battery_size)+" kWh battery.")
class EletricCar(Car):
def __init__(self,make,model,year):
'''先初始化父类属性,再初始化子类特有的属性'''
super().__init__(make,model,year)
self.battery = Battery(80)
my_tesla = EletricCar('tesla','model_s','2018')
print(my_tesla.get_description())
my_tesla.battery.describe_battery()
4.导入类
Python允许把类或函数存储在模块中,然后再主程序中导入需要的模块。
- 导入单个类
创建模块car.py 存储Car类。另外建一个文件,my_car.py,在其中导入Car类并创建实例:
from car import Car
my_car = Car('baoma',730,2018)
my_car.get_description()
- 在一个模块中存储多个类
例如可以把Car类,ElectricCar类和Battery类都放在car.py模块中。
- 从一个模块中导入多个类
from car import Car,EletricCar
my_n_car = Car('AE86','levin',2011)
print(my_n_car.get_description())
print("-------------------------------")
my_e_car = EletricCar('telsa','modelll',2100)
print(my_e_car.get_description())
my_e_car.battery.describe_battery()
- 导入整个模块
import car
my_n_car = car.Car('AE86','levin',2011)
print(my_n_car.get_description())
print("-------------------------------")
my_e_car = car.EletricCar('telsa','modelll',2100)
print(my_e_car.get_description())
my_e_car.battery.describe_battery()
- 导入模块中的所有类
from module_name import *
- 在一个模块中导入另一个模块
把Car类单独放在car.py模块中,ElectricCar类和Battery类放在electric_car.py模块中。
ElectricCar类需要访问父类,所以在electric_car模块中需要导入car模块:
from car import Car
在my_car.py文件中,可以从两个模块中分别导入:
from car import Car
from electric_car import EletricCar
my_n_car = car.Car('AE86','levin',2011)
print(my_n_car.get_description())
print("-------------------------------")
my_e_car = car.EletricCar('telsa','modelll',2100)
print(my_e_car.get_description())
5.Python标准库
python标准库是一组模块,安装Python后都会包含。可以使用import 和 from 使用Python内建的函数或类,以及其他程序员编写的函数或类。
from collections import OrderedDict
from keras import LSTM,Conv2d