读书笔记「Python编程:从入门到实践」_9.类
9.1 创建和使用类
面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。
OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。
编写类时,你定义一大类对象都有的通用行为。
基于类创建对象 时,每个对象都自动具备这种通用行为,然后可根据需要赋予每个对象独特的个性。
根据类来创建对象被称为实例化 ,这让你能够使用类的实例。
9.1.1 创建Dog类
class Dog():
#在Python中,首字母大写的名称指的是类。这个类定义中的括号是空的,因为我们要从空白创建这个类。
#class ClassName(object):在Python 2.7中创建类时,需要做细微的修改——在括号内包含单词object
"""一次模拟小狗的简单尝试"""
#我们编写了一个文档字符串,对这个类的功能作了描述。
def __init__(self, name, age):
#方法__init__() 是一个特殊的方法,每当你根据Dog 类创建新实例时,Python都会自动运行它。
#在这个方法的名称中,开头和末尾各有两个下划线,这是一种约定,旨在避免Python默认方法与普通方法发生名称冲突。
#方法__init__() 并未显式地包含return 语句,但Python自动返回一个表示这条小狗的实例
"""初始化属性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!")
9.1.2 根据类创建实例
我们通常可以认为首字母大写的名称(如Dog )指的是类,而小写的名称(如my_dog )指的是根据类创建的实例。
句点表示法在Python中很常用,这种语法演示了Python如何获悉属性的值。
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.")
9.2 使用类和实例
9.2.1 Car类
9.2.2 给属性指定默认值
9.2.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) + " 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 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()
#通过方法修改属性的值
my_new_car.update_odometer(500)
my_new_car.read_odometer()
my_new_car.update_odometer(50)
my_new_car.read_odometer()
#通过方法对属性的值进行递增
my_new_car.increment_odometer(10)
my_new_car.read_odometer()
2016 Audi A4
This car has 23 miles on it.
This car has 500 miles on it.
You can't roll back an odometer!
This car has 500 miles on it.
9.3 继承
9.3.1 子类的方法__init__()
9.3.2 Python 2.7中的继承
9.3.3 给子类定义属性和方法
9.3.4 重写父类的方法
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) + " 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
def fill_gas_tank(self):
"""加满油"""
print("Now gas tank is full!")
from car import Car
#让Python打开模块car ,并导入其中的Car 类。这样我们就可以使用Car 类 class ElectricCar(Car): #必须在括号内指定父类的名称
"""电动汽车的独特之处"""
def __init__(self, make, model, year):
"""初始化父类的属性"""
super().__init__(make, model, year) #supper是一个特殊函数,帮助Python将父类和子类关联起来
#Python 2.7中使用继承时 需要两个实参:子类名和对象self
#super(ElectricCar, self).__init__(make, model, year)
#给子类定义属性和方法
self.battery_size = 400
#给子类定义属性和方法
def describe_battery(self):
"""打印一条描述电瓶容量的消息"""
print("This car has a " + str(self.battery_size) + "-kWh battery.")
#重写父类的方法,与要重写的父类方法同名。这样,Python将不会考虑这个父类方法
def fill_gas_tank(self):
"""电动汽车没有油箱"""
print("This car doesn't need a gas tank!") my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.fill_gas_tank()
my_tesla.describe_battery()
2016 Tesla Model S
This car doesn't need a gas tank!
This car has a 400-kWh battery.
9.3.5 将实例用作属性
from car import Car
#让Python打开模块car ,并导入其中的Car 类。这样我们就可以使用Car 类
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 ElectricCar(Car): #必须在括号内指定父类的名称
"""电动汽车的独特之处"""
def __init__(self, make, model, year):
"""初始化父类的属性"""
super().__init__(make, model, year)
#将实例用作属性
#要将类的一部分作为一个独立的类提取出来。你可以将大型类拆分成多个协同工作的小类。
self.battery = Battery() my_tesla = ElectricCar('tesla', 'model s', 2016)
my_tesla.battery.battery_size=80
my_tesla.battery.describe_battery()
This car has a 80-kWh battery.
9.3.6 模拟实物
从较高的逻辑层面(而不是语法层面)考虑;你考虑的不是Python,而是如何使用代码来表示实物。
到达这种境界后,你经常会发现,现实世界的建模方法并没有对错之分。有些方法的效率更高,但要找出效率最高的表示法,需要经过一定的实践。
只要代码像你希望的那样运行,就说明你做得很好!即便你发现自己不得不多次尝试使用不同的方法来重写类,也不必气馁;要编写出高效、准确的代码,都得经过这样的过程。
9.4 导入类
9.4.1 导入单个类
from car import Car
import 语句让Python打开模块car ,并导入其中的Car 类。这样我们就可以使用Car 类了,就像它是在这个文件中定义的一样
9.4.2 在一个模块中存储多个类
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) + " 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
def fill_gas_tank(self):
"""加满油"""
print("Now gas tank is full!") 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 ElectricCar(Car): #必须在括号内指定父类的名称
"""电动汽车的独特之处"""
def __init__(self, make, model, year):
"""初始化父类的属性"""
super().__init__(make, model, year)
#将实例用作属性
#要将类的一部分作为一个独立的类提取出来。你可以将大型类拆分成多个协同工作的小类。
self.battery = Battery()
mycar.py
from car import ElectricCar my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()
2016 Tesla Model S
This car has a 70-kWh battery.
9.4.3 从一个模块中导入多个类
from car import Car, ElectricCar my_beetle = Car('volkswagen', 'beetle', 2016)
print(my_beetle.get_descriptive_name())
my_tesla = ElectricCar('tesla', 'roadster', 2016)
print(my_tesla.get_descriptive_name())
2016 Volkswagen Beetle
2016 Tesla Roadster
9.4.4 导入整个模块
使用语法 module_name.class_name 访问需要的类
import car my_beetle = car.Car('volkswagen', 'beetle', 2016)
print(my_beetle.get_descriptive_name())
my_tesla = car.ElectricCar('tesla', 'roadster', 2016)
print(my_tesla.get_descriptive_name())
2016 Volkswagen Beetle
2016 Tesla Roadster
9.4.5 导入模块中的所有类
要导入模块中的每个类,可使用下面的语法:from module_name import *
不推荐
① 没有明确地指出你使用了模块中的哪些类。
② 类名可能重复
from car import * my_beetle = Car('volkswagen', 'beetle', 2016)
print(my_beetle.get_descriptive_name())
my_tesla = ElectricCar('tesla', 'roadster', 2016)
print(my_tesla.get_descriptive_name())
9.4.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) + " 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
def fill_gas_tank(self):
"""加满油"""
print("Now gas tank is full!")
electricCar.py
from car import Car
#让Python打开模块car ,并导入其中的Car 类。这样我们就可以使用Car 类
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 ElectricCar(Car): #必须在括号内指定父类的名称
"""电动汽车的独特之处"""
def __init__(self, make, model, year):
"""初始化父类的属性"""
super().__init__(make, model, year)
#将实例用作属性
#要将类的一部分作为一个独立的类提取出来。你可以将大型类拆分成多个协同工作的小类。
self.battery = Battery()
myCar.py
from car import Car
from electricCar import ElectricCar my_beetle = Car('volkswagen', 'beetle', 2016)
print(my_beetle.get_descriptive_name())
my_tesla = ElectricCar('tesla', 'roadster', 2016)
print(my_tesla.get_descriptive_name())
2016 Volkswagen Beetle
2016 Tesla Roadster
9.4.7 自定义工作流程
一开始应让代码结构尽可能简单。先尽可能在一个文件中完成所有的工作,确定一切都能正确运行后,再将类移到独立的模块中。
如果你喜欢模块和文件的交互方式,可在项目开始时就尝试将类存储到模块中。先找出让你能够编写出可行代码的方式,再尝试让代码更为组织有序。
9.5 Python标准库
Python标准库 是一组模块,安装的Python都包含它
下面来看模块collections 中的一个类——OrderedDict 。来创建一个空的有序字典
from collections import OrderedDict
favorite_languages = OrderedDict()
favorite_languages['jen'] = 'python'
favorite_languages['sarah'] = 'c'
favorite_languages['edward'] = 'ruby'
favorite_languages['phil'] = 'python'
for name, language in favorite_languages.items():
print(name.title() + "'s favorite language is " +
language.title() + ".")
Jen's favorite language is Python.
Sarah's favorite language is C.
Edward's favorite language is Ruby.
Phil's favorite language is Python.
9.6 类编码风格
类名应采用驼峰命名法 ,即将类名中的每个单词的首字母都大写,而不使用下划线。
实例名和模块名都采用小写格式,并在单词之间加上下划线。 ※抱歉例子中的模块名命名不规范
对于每个类,都应紧跟在类定义后面包含一个文档字符串。这种文档字符串简要地描述类的功能,并遵循编写函数的文档字符串时采用的格式约定。
每个模块也都应包含一个文档字符串,对其中的类可用于做什么进行描述。
可使用空行来组织代码,但不要滥用。在类中,可使用一个空行来分隔方法;而在模块中,可使用两个空行来分隔类。
需要同时导入标准库中的模块和你编写的模块时,先编写导入标准库模块的import 语句,再添加一个空行,然后编写导入你自己编写的模块的import 语句。
读书笔记「Python编程:从入门到实践」_9.类的更多相关文章
- 读书笔记「Python编程:从入门到实践」_11.测试函数
11.1 测试函数 要学习测试,得有要测试的代码.下面是一个简单的函数,它接受名和姓并返回整洁的姓名: def get_formatted_name(first, last): "" ...
- 读书笔记「Python编程:从入门到实践」_10.文件和异常
10.1 从文件中读取数据 10.1.1 读取整个文件 with open(~) as object: contents=object.read() with open('C:/Users/jou/ ...
- 读书笔记「Python编程:从入门到实践」_8.函数
8.1 定义函数 def greet_user(): # def 来告诉Python你要定义一个函数.这是函数定义 """Hello World""& ...
- 读书笔记「Python编程:从入门到实践」_7.用户输入和while循环
7.1 函数input()的工作原理 函数input() 让程序暂停运行,等待用户输入一些文本.获取用户输入后,Python将其存储在一个变量中,以方便你使用. message = input(&qu ...
- 读书笔记「Python编程:从入门到实践」_6.字典
6.1 一个简单的字典 alien_0 = {'color': 'green', 'points': 5} print(alien_0['color']) print(alien_0['points' ...
- 读书笔记「Python编程:从入门到实践」_5.if语句
5.1 一个简单示例 cars = ['audi', 'bmw', 'subaru', 'toyota'] for car in cars: if car == 'bmw': print(car.up ...
- 读书笔记「Python编程:从入门到实践」_4.操作列表
4.1 遍历整个列表 4.1.1 深入地研究循环 4.1.2 在for循环中执行更多的操作 4.1.3 在for循环结束后执行一些操作 例 magicians = ['alice', ' ...
- 读书笔记「Python编程:从入门到实践」_3.列表简介
3.1 列表是什么 列表 由一系列按特定顺序排列的元素组成. 在Python中,用方括号([] )来表示列表,并用逗号来分隔其中的元素. 3.1.1 访问列表元素 指出列表的名称,再指出元素的索引 ...
- 读书笔记「Python编程:从入门到实践」_2.变量和简单数据类型
做了大半年RPA了,用的工具是Kapow. 工作没有那么忙,不想就这么荒废着,想学点什么.就Python吧. 为期三个月,希望能坚持下来. 2.1 变量的命名和使用 变量名只能包含字母.数字和下划线. ...
随机推荐
- The merchant
The merchant Time Limit: 3000MS Memory Limit: 65536K Description There are N cities in a cou ...
- hdu 4171 最短路
#include<stdio.h> #include<string.h> #include<queue> #include<iostream> usin ...
- debug jdk source can't watch variable what it is
https://www.cnblogs.com/shuaiqing/p/7525841.html https://stackoverflow.com/questions/18255474/debug- ...
- MySQL终端(Terminal)命令基本操作(转)
注意:MySQL数据库命令不区分大小写.但在MAC的终端,如果你想使用tab自动补全命令,那么你就必须使用大写,这样MAC的终端才会帮你补全命令,否则你按N遍tab都不会有响应. 1.数据库(data ...
- Clojure:两步发送iOS推送通知(apns)
首先在project.clj中,添加对notnoop 类库的引用:[com.notnoop.apns/apns "0.2.3"] 然后使用如下方法就可以发送推送消息了: (ns d ...
- Oracle学习(12):存储过程,函数和触发器
存储过程和存储函数 l存储在数据库中供全部用户程序调用的子程序叫存储过程.存储函数. 注意:存储过程与存储函数声明变量时,用的是as 而不是declare 存储过程与存储函数差别 存储过程不带有返 ...
- 对扩展openflow协议的一点思考
软件定义X变得越来越火,正所谓,Software is eating the world. 软件定义网络也是如此.不论是在工业界还是学术界都将是一次伟大的革命,都在紧随着这个行业的方向,找自 ...
- job调度时间格式
*/5 * * * * ?---------------每隔5秒执行一次0 */1 * * * ?---------------每隔1分钟执行一次0 0 23 * * ?--------------- ...
- luogu1063 能量项链
题目大意 有一串项链,项链上的每个珠子有首尾两个数字,首尾相连的两个珠子的尾数字和头数字相同.每次选择相连的一对珠子,得到第一个项链的首数字*第一个项链的尾数字(第二个项链的首数字)*第二个项链的尾数 ...
- Middle-help 终极实现元素水平垂直居中
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...