Python基础知识
1.变量和简单数据类型
1.1变量
- 变量只能包含字母、数字、下划线,并且不能以数字开头
- 变量名不能包含空格
- 不要讲python关键字和函数作为变量名。
- 变量名应简短又具有描述行
- 被赋值的内容应该用双引号或单引号括起来
1.2字符串
- title():将字符串首字母变为大写
- upper(): 将字符串变为大写
- lower(): 将字符串变为小写
- isupper():判断字符串是否为大写
- islower():判断字符串是否为小写
- isalpha():如果字符串只包含字母,并且非空,则返回True
- isalnum():如果字符串只包含字母和数字,并且非空,则返回True
- isdecimal():如果字符串只包含数字字符,并且非空,则返回True
- isspace():如果字符串只包含空格,制表符和换行,并且非空,则返回True
- istitle():如果字符串仅包含以大写字母开头,后面都是小写字母的单词,并且非空,则返回True
- 合并拼接字符串使用+号
- 使用/t代表制表符;/n代表换行符
1.2.1字符串删除空白
- strip():删除字符串两边空白
- rstrip():删除字符串右空白
- lstrip():删除字符串左空白
1.2.2用rjust()、ljust()和center()方法对齐文本
rjust()和ljust()字符串方法返回调用他们的字符串的填充版本,通过插入空格来对齐文本。
1.2.3字符串split()和join()方法
join()方法针对一个字符串而调用的,并且传入一个列表值
split()方法正好与join()方法相反,它针对一个字符串调用,返回一个字符串列表
语法:
str.split(sep,maxsplit)
此方法中各部分参数的含义分别是:
str:表示要进行分割的字符串;
sep:用于指定分隔符,可以包含多个字符。此参数默认为 None,表示所有空字符,包括空格、换行符“\n”、制表符“\t”等。
maxsplit:可选参数,用于指定分割的次数,最后列表中子串的个数最多为 maxsplit+1。如果不指定或者指定为 -1,则表示分割次数没有限制。
1.2.4原始字符串
可以在字符串开始的引号之前加上r,使它成为原始字符串。原始字符串完全忽略所有转义字符,打印出字符中所有到斜杠。例如:
1.2.5startswith()和endswith()方法
用来验证字符串以某个字符串开头或结尾,如果只需要验证字符串的开始或结束部分是否等于另一个字符串,而不是整个字符串,这些方法就可以替代操作符==,这个很有用。
1.2.6用pyperclip模块拷贝粘贴字符串
这个是第三方模块需要进行安装使用
2.列表
2.1 列表增删改查
- 索引:从0开始
- 修改列表元素:如:motorcycles = ['honda', 'yamaha', 'suzuki'] 把列表motorcycles中第一个元素honda改成ducati。motorcycles[0] = 'ducati'
- 在列表中添加元素:使用append()在列表末尾添加元素。如motorcycles = ['honda', 'yamaha', 'suzuki']在列表末尾添加ducati元素,motorcycles.append('ducati')
- 在列表中添加元素:使用insert()在列表中插入元素。如motorcycles = ['honda', 'yamaha', 'suzuki']在索引0处添加ducati元素,motorcycles.insert(0, 'ducati')
- 从列表中删除元素:如果知道要删除的元素在列表中的位置,可以使用del()语句删除元素。如motorcycles = ['honda', 'yamaha', 'suzuki']删除索引下标为0的honda字符串,则可以使用del motorcycles[0]
- 从列表中删除元素:有时候,你要将元素从列表中删除,并接着使用它,可以使用pop()删除元素,方法pop()可删除列表末尾的元素。如列表motorcycles = ['honda', 'yamaha', 'suzuki'],我想使用suzuki字段并对他重新赋值,popped_motorcycle = motorcycles.pop(),此时变量popped_motorcycle的值就是suzuki。
- 从列表中删除元素:也可以使用pop()来删除列表中任何元素。只需要在括号中指定要删除的元素的索引即可。如motorcycles = ['honda', 'yamaha', 'suzuki'],删除索引为0的honda元素,first_owned = motorcycles.pop(0)
- 从列表中删除元素:有时候,你不知道要从列表中删除的值所处的位置,如果你只知道要删除的元素的值,可使用方法remove(),如motorcycles = ['honda', 'yamaha', 'suzuki'],从列表中删除suzuki元素,motorcycles.remove('suzuki'),注意 方法remove()只删除第一个指定的值。如果要删除的值可能在列表中出现多次,就需要 使用循环来判断是否删除了所有这样的值
2.2 列表组织排序
在你创建的列表中,元素的排列顺序通常是无法预测的,因为你并非总能控制用户提供数据的顺序。这虽然在大多数情况下是不可避免的,但你经常需要以特定的顺序呈现信息。有时候你希望保留列表元素最初的排列顺序,而有时候又需要调整排列顺序。Python提供了很多组织列表的方式,可根据具体情况选用。
- 对列表进行排序:使用sort()方法对列表进行永久性排序,如果需要按照倒序进行排序,可以使用reverse=True。如cars = ['bmw', 'audi', 'toyota', 'subaru'],使用cars.sort(),结果为['audi', 'bmw', 'subaru', 'toyota'];如果增加cars.sort(reverse=True)参数,结果变为['toyota', 'subaru', 'bmw', 'audi']
- 对列表进行排序:使用sorted()方法对列表临时排序,cars = ['bmw', 'audi', 'toyota', 'subaru'],print(sorted(cars)),如果需要进行反向排序,可以增加reverse=True参数
- 倒着打印列表:要反转列表元素的排列顺序,可以使用reverse()方法。
- 确定列表长度:可以使用len()快速确认列表长度。
2.3 创建数值列表
- 使用range()函数创建数字列表,可使用list()函数将range()结果准换为列表。
number_lists = list(range(1,6)) print(number_lists) 结果为 [1, 2, 3, 4, 5] ====================== number_lists = [] for value in range(1,11): number_list = value ** 2 number_lists.append(number_list) print(number_lists) 结果为 [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
- 对数字列表执行简单的统计计算
number_lists = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] 最大值 print(max(number_lists)) 最小值 print(min(number_lists)) 总和 print(sum(number_lists))
- 列表解析
number_lists = [value ** 2 for value in range(1,11)] print(number_lists) 结果为: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
2.4 列表切片
- 切片:如所示players = ['charles', 'martina', 'michael', 'florence', 'eli'] 对结果进行打印print(players[2:]),结果为:['michael', 'florence', 'eli']
- 对切片列表进行遍历:如下所以是获取列表中前三个值
players = ['charles', 'martina', 'michael', 'florence', 'eli'] for value in players[:3]: print(value)
- 复制列表:你经常需要根据既有列表创建全新的列表。下面来介绍复制列表的工作原理,以及复制列表可提供极大帮助的一种情形。要复制列表,可创建一个包含整个列表的切片,方法是同时省略起始索引和终止索引([:])。 这让Python创建一个始于第一个元素,终止于最后一个元素的切片,即复制整个列表。
my_players = ['charles', 'martina', 'michael', 'florence', 'eli'] friend_players = my_players[:] #打印两个列表 print(my_players) print(friend_players) #为了证明是两个列表,对两个列表添加不同的内容 my_players.append('dog') friend_players.append('pig') print(my_players) print(friend_players)
3.元组
Python将不能修改的值称为不可变的,而不可变的列表被称为元组。
元组看起来犹如列表,但使用圆括号而不是方括号来标识。定义元组后,就可以使用索引来 访问其元素,就像访问列表元素一样。
my_players = ('charles', 'martina', 'michael', 'florence', 'eli') for value in my_players: print(value)
4.if语句
4.1条件测试
- ==:是否相等
- >:是否大于
- <:是否小于
- >=:是否大于等于
- <=:是否小于等于
- !=:是否不等于
- in:是否包含
- not in:是否不包含
- and:与
- or:或
- bool值,空字符串、空列表、空元组、空字典、0都是False
4.2if语句格式
- if <条件>:单分支if语句
- if <条件>:else:双分支if语句
- if <条件>:elif <条件>:else:多分支if语句
5.字典
在Python中,字典是一系列键—值对。每个键都与一个值相关联,你可以使用键来访问与之相关联的值。与键相关联的值可以是数字、字符串、列表乃至字典。事实上,可将任何Python对 象用作字典中的值。
5.1 字典常规操作
- 获取字典内容
alien_0 = {'color': 'green', 'points': 5} print(alien_0['color'])
- 获取字典内容get()方法
dict_test = {1:'hh',2:'kk'} dict1 = dict_test.get(3,0) print(dict1) #获取key键为3的值,没有补充默认值0,而不会像上边案例会导致报错
- 获取字典内容setdefault()方法
dict_test = {1:'hh',2:'kk'} print(dict_test) dict_test.setdefault(3,'mm') print(dict_test) dict_test.setdefault(3,'oo') print(dict_test) #setdefault第一个键指定获取的key,第二个值指定可以对应的值,如果key不存在,则创建对应的键值对,如果存储则显示,key对应的值
setdefault()方法示例:
message = 'It was a bright cold day in April, and the clocks were striking thirteen.' dict_count = {} for character in message: dict_count.setdefault(character,0) dict_count[character] = dict_count[character] + 1 print(dict_count) #计算message字符串每个字符出现的次数,每个字符作为键,通过setdefault方法将键初始值设置为0,通过+1统计每个键对应值出现的次数
- 字典增加内容
alien_0 = {'color': 'green', 'points': 5} alien_0['x']=0 alien_0['y']=25 print(alien_0)
- 修改字典中的值
alien_0 = {'x_position': 0, 'y_position': 25, 'speed': 'medium'} print("x_position is:" + str(alien_0['x_position'])) if alien_0['speed'] == 'slow': x_increment = 1 elif alien_0['speed'] == 'medium': x_increment = 2 else: x_increment = 3 alien_0['x_position'] = x_increment + alien_0['x_position'] print("new x_position is:" + str(alien_0['x_position']))
- 字典删除键值对
对于字典中不再需要的信息,可使用del语句将相应的键—值对彻底删除。使用del语句时,必须指定字典名和要删除的键。
alien_0 = {'x_position': 0, 'y_position': 25, 'speed': 'medium'} print(alien_0) del alien_0['speed'] print(alien_0)
- 遍历字典
一个Python字典可能只包含几个键—值对,也可能包含数百万个键—值对。鉴于字典可能包含大量的数据,Python支持对字典遍历。字典可用于以各种方式存储信息,因此有多种遍历字典的 方式:可遍历字典的所有键—值对、键或值。
- 遍历字典中所有键和值,items()方法变量字典的key和value值
alien_0 = {'x_position': 0, 'y_position': 25, 'speed': 'medium'} for k,v in alien_0.items(): print(k + " is a " + str(v))
2. 遍历字典中所有键,在不需要使用字典中的值时,方法keys()很有用。
alien_0 = {'x_position': 0, 'y_position': 25, 'speed': 'medium'} for k in alien_0.keys(): print(k)
3. 遍历字典中所有值,如果你感兴趣的主要是字典包含的值,可使用方法values(),它返回一个值列表,而不包含 任何键。
alien_0 = {'x_position': 0, 'y_position': 25, 'speed': 'medium'} for v in alien_0.values(): print(v)
5.2 嵌套
有时候,需要将一系列字典存储在列表中,或将列表作为值存储在字典中,这称为嵌套。你 可以在列表中嵌套字典、在字典中嵌套列表甚至在字典中嵌套字典。
- 列表嵌套字典
#创建一个用于存储外星人信息的空列表
aliens = []
#批量创建30个外星人 for aliens_num in range(30): new_aliens = {'color': 'green', 'points': 5, 'speed': 'slow'} aliens.append(new_aliens) #打印前5个外星人信息 for alien in aliens[:5]: print(alien) #统计创建了多少个外星人 print("creat alien number: " + str(len(aliens)))
鉴于我们要修改前三个外星人,需要遍历一个只包含这些外星人的切片。当前,所有外星人都是绿色的,但情况并非总是如此,因此我们编写了一条if语句来确保只修改绿色外星人。如果外星人是绿色的,我们就将其颜色改为'yellow',将其速度改为'medium',并将其点数改为10, 如下面的输出所示:
aliens = [] for aliens_num in range(30): new_aliens = {'color': 'green', 'points': 5, 'speed': 'slow'} aliens.append(new_aliens) #判断前3个外星人如果是绿色就改为黄色 for alien in aliens[:3]: if alien['color'] == 'green': alien['color'] = 'yellow' alien['points'] = 10 alien['speed'] = 'medium'
#打印前5个外星人信息 for alien in aliens[:5]: print(alien) print("==========================") #统计创建了多少个外星人 print("creat alien number: " + str(len(aliens)))
- 在字典中存储列表
每当需要在字典中将一个键关联到多个值时,都可以在字典中嵌套一个列表。
favorite_languages = { 'jen': ['python', 'ruby'], 'sarah': ['c'], 'edward': ['ruby', 'go'], 'phil': ['python', 'haskell'], } #打印每个人喜欢的语言有哪些 for name,languages in favorite_languages.items(): print(name.title() + " like language is:") for language in languages: print(language)
- 在字典中嵌套字典
可在字典中嵌套字典,但这样做时,代码可能很快复杂起来。例如,如果有多个网站用户,每个都有独特的用户名,可在字典中将用户名作为键,然后将每位用户的信息存储在一个字典中, 并将该字典作为与用户名相关联的值。在下面的程序中,对于每位用户,我们都存储了其三项信息:名、姓和居住地;为访问这些信息,我们遍历所有的用户名,并访问与每个用户名相关联的 信息字典:
users = { 'aeinstein': { 'first': 'albert', 'last': 'einstein', 'location': 'princeton', }, 'mcurie': { 'first': 'marie', 'last': 'curie', 'location': 'paris', }, } #打印用户,并打印用户全名和所居住的地址 for username,userinfo in users.items(): print("\nusername is:" + username) full_name = userinfo['first'] + userinfo['last'] userlocal = userinfo['location'] print("\tfull_name is:" + full_name) print("\tuser location is:" + userlocal)
6.用户输入和while循环
6.1用户输入input()方法
有时候,提示可能超过一行,例如,你可能需要指出获取特定输入的原因。在这种情况下,可将提示存储在一个变量中,再将该变量传递给函数input()。这样,即便提示超过一行,input() 语句也非常清晰。
messages = "If you tell us who you are, we can personalize the messages you see." messages += "\nWhat is your first name? " messages += "\nplease code:" message = input(messages) print(message)
注意:如果你使用的是Python 2.7,应使用函数raw_input()来提示用户输入。这个函数与Python 3 中的input()一样,也将输入解读为字符串。
6.2标志
将active设置为True标志,如果标志不改变,会一直循环下去。
re = 'please input something: ' active = True while active: message = input(re) if message == 'quit': active = False else: print(message)
6.3如何跳出循环
- break:终止循环
- continue:终止本次循环
6.4使用while处理列表和字典
for循环是一种遍历列表的有效方式,但在for循环中不应修改列表,否则将导致Python难以跟踪其中的元素。要在遍历列表的同时对其进行修改,可使用while循环。通过将while循环同列 表和字典结合起来使用,可收集、存储并组织大量输入,供以后查看和显示。
6.4.1在列表之间移动元素
假设有一个列表,其中包含新注册但还未验证的网站用户;验证这些用户后,如何将他们移到另一个已验证用户列表中呢?一种办法是使用一个while循环,在验证用户的同时将其从未验 证用户列表中提取出来,再将其加入到另一个已验证用户列表中。
unconfirmed_users = ['cat','dog','pig'] confirmed_users = [] while unconfirmed_users: confirmed_user = unconfirmed_users.pop() print("The unconfirmed user is " + confirmed_user.title()) confirmed_users.append(confirmed_user) # 显示confirmed用户列表内容 print("confirmed user list is:") for confirmed_user in confirmed_users: print(confirmed_user.title())
6.4.2删除特定值的所有列表元素
zoon = ['cat','dog','cat','pig','cat'] #如果想移除所有cat元素,可使用remove方法,简单的remove方法只能移除第一个匹配的元素,所以需要用while循环进行移除,直到列表中不存在cat元素 print(zoon) while 'cat' in zoon: zoon.remove('cat') print(zoon)
6.4.3使用用户输入来填充字典
#设置一个空字典 responses = {} # 设置一个标志 active = True while active: #输入两条信息询问用户名字,和喜欢的动物 name = input("watch you is name:") animals = input("would you like animals:") #将用户回答内容加入到字典中 responses[name] = animals #询问用户是否需要继续回答问题 req = input("would you gooning yes or no? ") if req == 'no': active = False #打印字典内容 print(responses)
7.函数
要执行函数定义的特定任务,可调用该函数。需要在程序中多次 执行同一项任务时,你无需反复编写完成该任务的代码,而只需调用 执行该任务的函数,让Python运行其中的代码。
def greet_user(username): print(username) greet_user('wukong')
以上代码,username代表形参、wukong代表实参
7.1传递实参
鉴于函数定义中可能包含多个形参,因此函数调用中也可能包含多个实参。向函数传递实参的方式很多,可使用位置实参,这要求实参的顺序与形参的顺序相同;也可使用关键字实参,其中每个实参都由变量名和值组成;还可使用列表和字典。
7.2返回值
函数并非总是直接显示输出,相反,它可以处理一些数据,并返回一个或一组值。函数返回的值被称为返回值。在函数中,可使用return语句将值返回到调用函数的代码行。
def greet_name(undef_name,conform_name): while undef_name: req_name = undef_name.pop() print("write name lalala " + req_name.title()) conform_name.append(req_name) def list_name(conform_name): for name in conform_name: print(name) undef_name = ['dog','pig','cat'] conform_name = [] greet_name(undef_name,conform_name) list_name(conform_name)
以上代码示例,通过函数会将undef_name列表pop空,如果想使原始列表保留,可以使用列表复制的方法,如greet_name(undef_name[:],conform_name)
8.类
8.1 代码示例:
class User(): #初始化属性fist_name,last_name,age,like def __init__(self,fist_name,last_name,age,like): self.fist_name = fist_name self.last_name = last_name self.age = age self.like = like def describe_user(self): print(self.fist_name.title(),self.last_name.title(),"is " + str(self.age) + " old,"," likes " + self.like ) def greet_user(self): full_name = self.fist_name.title() + self.last_name.title() print(full_name,"welcome to python word") user = User('wu','kong','18','playbool') user.describe_user() user.greet_user()
根据约定,在Python中,首字母大写的名称指的是类。 这个类定义中的括号是空的,因为我们要从空白创建这个类。
方法__init__()
类中的函数称为方法;你前面学到的有关函数的一切都适用于方法,就目前而言,唯一重要 的差别是调用方法的方式。
__init__():定义了5个行参,self,fist_name,last_name,age,like,self是必不可少的,还必须位于其他形参前面。为何在方法定义中包含self呢?因为python调用__init__()方法来创建user实例时,将自动传入实参self。
下面定义的describe_user和greet_user方法,也会自动传递self引用的形参。
以self为前缀的变量都可供类中的所有方法使用,我们还可以通过类的任何实例来访问这些变量。
注意:在Python 2.7中创建类时,需要做细微的修改——在括号内包含单词object:
class ClassName(object): --snip--
将实例存储到user变量中,通过user变量加点的方式调用类中的方法。访问实例的属性,可使用句点表示法。
8.2 使用类和实例
如下代码:定义了一个汽车类,并定义了一个获取汽车信息的方法
class Car(): def __init__(self,make,model,year): self.make = make self.model = model self.year = year def get_descripte_name(self): long_name = str(self.year) + " " + self.make + " " + self.model return long_name.title() my_new_car = Car('aodi','a4','2023') print(my_new_car.get_descripte_name())
目前增加一个变量odometer_reading,定义汽车出厂里程为0.我们还添加了一个名为read_odometer()的方法,用于读取汽车的里程表:
class Car(): def __init__(self,make,model,year): self.make = make self.model = model self.year = year #定义一个默认汽车里程变量,初始值为0 self.odometer_reading = 0 def get_descripte_name(self): long_name = str(self.year) + " " + self.make + " " + self.model return long_name.title() #定义一个方法,获取汽车里程 def read_odometer(self): print("The cat odometer is " + str(self.odometer_reading)) my_new_car = Car('aodi','a4','2023') print(my_new_car.get_descripte_name()) my_new_car.read_odometer()
修改汽车里程值,以下有三种方法:
方法一:通过改属性的值,最简单的方式是通过实例直接访问它。如下代码,直接将里程数改为23
class Car(): def __init__(self,make,model,year): self.make = make self.model = model self.year = year #定义一个默认汽车里程变量,初始值为0 self.odometer_reading = 0 def get_descripte_name(self): long_name = str(self.year) + " " + self.make + " " + self.model return long_name.title() #定义一个方法,获取汽车里程 def read_odometer(self): print("The cat odometer is " + str(self.odometer_reading)) my_new_car = Car('aodi','a4','2023') print(my_new_car.get_descripte_name()) # 通过修改属性值,直接将里程值改为23 my_new_car.odometer_reading = 23 my_new_car.read_odometer()
方法二:通过方法修改属性的值,将大有裨益,这样,你就无需直接访问属性,而可以将值传递给一个方法,有他那边进行更新,下面演示通过update_odometer()方法。
update_odometer()方法还做了判断,如果更新的里程数小于定义的里程数,说明有调表的嫌疑,打印告知不可以往回调。
class Car(): def __init__(self,make,model,year): self.make = make self.model = model self.year = year #定义一个默认汽车里程变量,初始值为0 self.odometer_reading = 0 def get_descripte_name(self): long_name = str(self.year) + " " + self.make + " " + self.model return long_name.title() #定义一个方法,获取汽车里程 def read_odometer(self): print("The cat odometer is " + str(self.odometer_reading)) #增加一个update_odometer方法用来更新里程 def update_odometer(self,mileage): if self.odometer_reading < mileage: self.odometer_reading = mileage else: print("You can't roll back an odometer!") my_new_car = Car('aodi','a4','2023') print(my_new_car.get_descripte_name()) #给update_odometer方法传递参数 my_new_car.update_odometer(33) my_new_car.read_odometer()
方法三:通过方法对属性值进行递增
有时候需要将属性值递增特定的量,而不是将其设置为全新的值。假设我们购买了一辆二手车,且从购买到登记期间增加了100英里的里程,下面的方法让我们能够传递这个增量,并相应地增加里程表读数:
class Car(): def __init__(self,make,model,year): self.make = make self.model = model self.year = year #定义一个默认汽车里程变量,初始值为0 self.odometer_reading = 0 def get_descripte_name(self): long_name = str(self.year) + " " + self.make + " " + self.model return long_name.title() #定义一个方法,获取汽车里程 def read_odometer(self): print("The cat odometer is " + str(self.odometer_reading)) #增加一个update_odometer方法用来更新里程 def update_odometer(self,mileage): if self.odometer_reading < mileage: 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('aodi','a4','2023') print(my_new_car.get_descripte_name()) #给update_odometer方法传递参数 my_new_car.update_odometer(33) my_new_car.read_odometer() #在里程33的基础上增加了10 my_new_car.increment_odometer(10) my_new_car.read_odometer()
8.3 继承
编写类时,并非总是要从空白开始。如果你要编写的类是另一个现成类的特殊版本,可使用继承。一个类继承另一个类时,它将自动获得另一个类的所有属性和方法;原有的类称为父类,而新类称为子类。子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。
class Car(): def __init__(self,make,model,year): self.make = make self.model = model self.year = year #定义一个默认汽车里程变量,初始值为0 self.odometer_reading = 0 def get_descripte_name(self): long_name = str(self.year) + " " + self.make + " " + self.model return long_name.title() #定义一个方法,获取汽车里程 def read_odometer(self): print("The cat odometer is " + str(self.odometer_reading)) #增加一个update_odometer方法用来更新里程 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 #定义了一个ElectricCar,继承了父类Car的所有属性 class ElectricCar(Car): def __init__(self,make,model,year): super().__init__(make,model,year) #定义一个电动车的实例 tesla = ElectricCar('tesla','model Y',2022) print(tesla.get_descripte_name())
让子类继承父类后,可添加区分子类和父类做需的新属性和方法。如下所示,增加一个电车特有的属性电瓶
class Car(): def __init__(self,make,model,year): self.make = make self.model = model self.year = year #定义一个默认汽车里程变量,初始值为0 self.odometer_reading = 0 def get_descripte_name(self): long_name = str(self.year) + " " + self.make + " " + self.model return long_name.title() #定义一个方法,获取汽车里程 def read_odometer(self): print("The cat odometer is " + str(self.odometer_reading)) #增加一个update_odometer方法用来更新里程 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 #定义了一个ElectricCar,继承了父类cat的所有属性 class ElectricCar(Car): def __init__(self,make,model,year): super().__init__(make,model,year) #增加一个电动车特有的属性,电瓶 self.battery_size = 700 #定义一个获取电瓶容量的方法 def describe_battery(self): print("The ElectricCar Battery is " + str(self.battery_size)) #定义一个电动车的实例 tesla = ElectricCar('tesla','model Y',2022) print(tesla.get_descripte_name()) tesla.describe_battery()
重写父类的方法
对于父类的方法,只要它不符合子类模拟的实物的行为,都可对其进行重写。为此,可在子 类中定义一个这样的方法,即它与要重写的父类方法同名。这样,Python将不会考虑这个父类方 法,而只关注你在子类中定义的相应方法。
假设Car类有一个名为fill_gas_tank()的方法,它对全电动汽车来说毫无意义,因此你可能 想重写它。下面演示了一种重写方式:
class Car(): def __init__(self,make,model,year): self.make = make self.model = model self.year = year #定义一个默认汽车里程变量,初始值为0 self.odometer_reading = 0 def get_descripte_name(self): long_name = str(self.year) + " " + self.make + " " + self.model return long_name.title() #定义一个方法,获取汽车里程 def read_odometer(self): print("The cat odometer is " + str(self.odometer_reading)) #增加一个update_odometer方法用来更新里程 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("The tanks is 100" ) #定义了一个ElectricCar,继承了父类cat的所有属性 class ElectricCar(Car): def __init__(self,make,model,year): super().__init__(make,model,year) #增加一个电动车特有的属性,电瓶 self.battery_size = 700 #定义一个获取电瓶容量的方法 def describe_battery(self): print("The ElectricCar Battery is " + str(self.battery_size)) def fill_gas_tank(self): print("The ElectricCar not tanks") #定义一个汽车的实例 my_cat = Car('aodi','A3',2044) print(my_cat.get_descripte_name()) my_cat.fill_gas_tank() #定义一个电动车的实例 tesla = ElectricCar('tesla','model Y',2022) print(tesla.get_descripte_name()) tesla.describe_battery() tesla.fill_gas_tank()
将实例用作属性
使用代码模拟实物时,你可能会发现自己给类添加的细节越来越多:属性和方法清单以及文件都越来越长。在这种情况下,可能需要将类的一部分作为一个独立的类提取出来。你可以将大型类拆分成多个协同工作的小类。
如下代码,将电瓶battery从ElectricCar电动车类中拆分出来,将Battery实例作为ElectricCar类的一个属性;
class Car(): def __init__(self,make,model,year): self.make = make self.model = model self.year = year #定义一个默认汽车里程变量,初始值为0 self.odometer_reading = 0 def get_descripte_name(self): long_name = str(self.year) + " " + self.make + " " + self.model return long_name.title() #定义一个方法,获取汽车里程 def read_odometer(self): print("The cat odometer is " + str(self.odometer_reading)) #增加一个update_odometer方法用来更新里程 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("The tanks is 100" ) class Battery(): def __init__(self,battery_size = 700): self.battery_size = battery_size # 定义一个获取电瓶容量的方法 def describe_battery(self): print("The ElectricCar Battery is " + str(self.battery_size)) #定义了一个ElectricCar,继承了父类cat的所有属性 class ElectricCar(Car): def __init__(self,make,model,year): super().__init__(make,model,year) self.battery = Battery() #定义一个电动车的实例 tesla = ElectricCar('tesla','model Y',2022) print(tesla.get_descripte_name()) tesla.battery.describe_battery()
如下代码,给电瓶又增加了里程功能,既对应的电瓶容量可以跑相应的里程数
class Car(): def __init__(self,make,model,year): self.make = make self.model = model self.year = year #定义一个默认汽车里程变量,初始值为0 self.odometer_reading = 0 def get_descripte_name(self): long_name = str(self.year) + " " + self.make + " " + self.model return long_name.title() #定义一个方法,获取汽车里程 def read_odometer(self): print("The cat odometer is " + str(self.odometer_reading)) #增加一个update_odometer方法用来更新里程 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("The tanks is 100" ) class Battery(): def __init__(self,battery_size = 700): self.battery_size = battery_size # 定义一个获取电瓶容量的方法 def describe_battery(self): print("The ElectricCar Battery is " + str(self.battery_size)) def get_range(self): if self.battery_size == 700: print("The ElectricCar is 240") elif self.battery_size == 880: print("The ElectricCar is 290") #定义了一个ElectricCar,继承了父类cat的所有属性 class ElectricCar(Car): def __init__(self,make,model,year): super().__init__(make,model,year) self.battery = Battery() #定义一个电动车的实例 tesla = ElectricCar('tesla','model Y',2022) print(tesla.get_descripte_name()) tesla.battery.describe_battery() tesla.battery.battery_size = 880 tesla.battery.get_range()
8.4 导入类
如以上定义了car.py的python代码,为了提高程序的可读性,将car代码作为模块进行导入调用。
导入单个类
from car import Car my_car = Car('bentian','honda',2016) print(my_car.get_descripte_name()) my_car.odometer_reading = 33 my_car.read_odometer()
导入多个类
from car import Car from car import ElectricCar my_car = Car('bentian','honda',2016) print(my_car.get_descripte_name()) my_tesla = ElectricCar('tesla','model x',2099) print(my_tesla.get_descripte_name())
9.文件和异常
9.1创建一个包含文件内容的列表--readlines()方法
使用关键字with时,open()返回的文件对象只在with代码块内可用。如果要在with代码块外访问文件的内容,可在with代码块内将文件的各行存储在一个列表中,并在with代码块外使用该列表:你可以立即处理文件的各个部分,也可推迟到程序后面再处理。
如下代码将读取文件的每一行放到file_line变量中,保存为一个列表,之后通过for循环读取列表内容。
with open('pi_digits.txt') as obj_file: file_line = obj_file.readlines() for i in file_line: print(i.rstrip())
9.2使用文件内容
注意:读取文本文件时,Python将其中的所有文本都解读为字符串。如果你读取的是数字,并要将其作为数值使用,就必须使用函数int()将其转换为整数,或使用函数float()将其转换为浮点数。
with open('pi_digits.txt') as obj_file: file_line = obj_file.readlines() lines = "" for i in file_line: lines += i.rstrip() print(lines) print(len(lines))
9.3写入文件
with open('pi_digits.txt','a+') as obj_file: obj_file.write("I love python!\n") obj_file.write("I love python too!\n")
9.4异常
Python使用被称为异常的特殊对象来管理程序执行期间发生的错误。每当发生让Python不知所措的错误时,它都会创建一个异常对象。如果你编写了处理该异常的代码,程序将继续运行; 如果你未对异常进行处理,程序将停止,并显示一个traceback,其中包含有关异常的报告。
异常是使用try-except代码块处理的。try-except代码块让Python执行指定的操作,同时告诉Python发生异常时怎么办。使用了try-except代码块时,即便出现异常,程序也将继续运行: 显示你编写的友好的错误消息,而不是令用户迷惑的traceback。
9.4.1 ZeroDivisionError错误
如下示例:让0作为除数,会产生ZeroDivisionError错误,使用try...except...来优化这个错误。
#print(5/0) try: print(5/0) except ZeroDivisionError: print("不可以")
如下代码写了一个简单的除法计算器
print("Give me two numbers, and I'll divide them.") print("Enter 'q' to quit.") while True: first_number = input("first_number: ") if first_number == 'q': break second_number = input("second_number: ") if second_number == 'q': break try: divide = int(first_number) / int(second_number) except ZeroDivisionError: print("不可以") else: print(divide)
9.5存储数据-json用法
很多程序都要求用户输入某种信息,如让用户存储游戏首选项或提供要可视化的数据。不管专注的是什么,程序都把用户提供的信息存储在列表和字典等数据结构中。用户关闭程序时,你几乎总是要保存他们提供的信息;一种简单的方式是使用模块json来存储数据。
模块json让你能够将简单的Python数据结构转储到文件中,并在程序再次运行时加载该文件中的数据。你还可以使用json在Python程序之间分享数据。更重要的是,JSON数据格式并非Python专用的,这让你能够将以JSON格式存储的数据与使用其他编程语言的人分享。这是一种轻便格式,很有用,也易于学习。
9.5.1 json.dump()方法,将数据存储到文件中
import json data = [1,2,3,4,5,6] file_name = 'pi_digits.txt' with open(file_name,'w') as obj_name: json.dump(data,obj_name)
9.5.2 json.load()方法,将数据从文件中读取到内存
import json file_name = 'pi_digits.txt' with open(file_name) as obj_file: file = json.load(obj_file) print(file)
9.5.3 保存和读取用户生成的数据
如下代码使用try语句判断如果user.json不存在则,创建文件并提示用户输入用户名,如果文件存储执行读取文件内容。
import json user_name = 'user.json' try: with open(user_name) as obj_name: user = json.load(obj_name) except BaseException as e: user = input("please user naem: ") with open(user_name,'w') as obj_name: json.dump(user,obj_name) else: print("welcome bake",user)
9.5.4 字符串转换为JSON
# echo '{"job":"developer","name":"lmx","sex":"male"}'|python -m json.tool { "job": "developer", "name": "lmx", "sex": "male" }
10测试代码
使用Python模块unittest中的工具来测试代码。学习编写测试用例,核实一系列输入都将得到预期的输出。你将看到测试通过了是什么样子,测试未通过又是什么样子,还将知道测试未通过如何有助于改进代码。你将学习如何测试函数和类,并将知道该为项目编写多少个测试。