实际操作中给变量取的名字要可读性强,我这里给变量取的名字非常简短,只是为了方便理解。
第 1 章 起步
win+s 输入cmd检查python是否安装成功, 或者win+s ,输入IDLE也可以使用python(IDLE是Python自带的)。
python文本编辑器:Geany,subline text,vs code ,pycharm,jupyter notebook。但是Geany,subline text在配置上很容易出现问题,不建议使用。
在vs code中运行.py文件
打开vs code——新建文件——文件另存为——某文件夹——保存类型选成:Python——在文件中输入print("Hello world! My name is Shuntai Yu.")——调试——启动调试——python file
在cmd中运行.py文件
cd 到.py文件所在位置——输入.py文件名——enter
第 2 章 变量和简单数据类型
在Python中, 用引号括起的都是字符串, 其中的引号可以是单引号, 也可以是双引号
.title()、.upper()、.lower()、+、\t,\n、.rstrip()、.lstrip()、.strip()、str() 、
修改大小写
message="Hello! shuntai yu !"
print(message.title()) #使每个单词首字母大写
print(message.upper()) #所有字母都大写
print(message.lower()) #所有字母都小写
合并(拼接)
#合并(拼接) 字符串
first_name="shuntai"
last_name="yu"
full_name=first_name + " " + last_name
print("Hello" + " " + full_name.title() + " " + "!")
添加空白和空白行
#制表符是\t,换行符是\n
print("python")
print("\npython") #换行
print("\tpython") #前面加一个空白
删除空白
tmp=" python "
print(tmp.rstrip()) #删除尾空白
print(tmp.lstrip()) #删除头空白
print(tmp.strip()) #删除两端空白
非字符转换成字符
# str() 它让Python将非字符串值表示为字符串
age = 23
message = "Happy " + str(age) + "rd Birthday!"
print(message)
python之禅
import this #python之禅
第 3 章 列表简介
Python 用[ ] 表示列表, 并用逗号来分隔元素。索引从0开始。
.append()、.insert()、del语句、.pop()、.remove()、.sort()、sorted()、.reverse()
提取元素
bicycles = ['trek', 'cannondale', 'redline', 'specialized','ducati']
print(bicycles[0])
print(bicycles[0].title()) #使首字母大写
print(bicycles[-1]) #索引为-1 表示倒数第一个列表元素,为-2为倒数第二个,依此类推。
更改,添加元素
bicycles[0] = 'ducati' #将第1个元素改成ducati
print(bicycles)
bicycles.append('zzz') #末尾附加元素
bicycles.insert(0, 'iii') #指定索引和值插入新元素
删除元素
del bicycles[0] #根据索引删除
popped_bircycle = bicycles.pop() #删除最后一个元素
print(bicycles)
print(popped_bicycle) #访问被删除的值
bicycles.pop(1) #指定索引获取任意元素
bicycles.remove('ducati') #根据元素删除
排序和确定元素个数
cars = ['bmw', 'audi', 'toyota', 'subaru']
cars.sort() #sort() 对列表进行永久性排序,变成cars.sort(reverse=True)则反向永久排序
print(cars)
print(sorted(cars)) #sorted() 对列表进行临时排序,也可传递参数reverse=True
print(cars)
cars.reverse() #永久反转排列顺序,使用两次可回到原顺序
print(cars)
len(cars) #确定列表元素个数
第4 章 操作列表
for循环、range()、enumerate()
tmp = [12,13,33,45,45,67,33,22,98]
foo = enumerate(tmp) # enumerate可以获取每个元素的索引和值
for id,bd in foo:
print(id,bd) #将会得到每个元素的索引和值
for循环
注意:缩进,冒号,[:]
foo = ['AAA', 'BBB', 'CCC']
for id in foo: #所谓遍历整个列表就是对列表中的每个元素执行相同的操作
print(id)
缩进
属于循环部分的代码要缩进,循环外部代码不缩进
magicians = ['alice', 'david', 'carolina']
for magician in magicians:
print(magician.title() + ", that was a great trick!")
print("I can't wait to see your next trick, " + magician.title() + ".\n") #缩进则每循环一次就执行一次,不缩进则只在循环结束时执行一次。
for id in range(1,5):
print(id)
for id in range(1,11,2): #2为步长
print(id)
foo = list(range(1,5))
print(foo)
数字列表创建、运算、解析
foo = [] #创建空list
for id in range(1,11):
arg = id**2
foo.append(arg) #要熟系.append的用法,foo.append(arg) 表示将arg的值追加到foo后面,for循环遍历每一个值,对每一个值求平方,将平方值追加到list里面。
print(foo)
sum(foo) #求和,若是min或者max则为求最小值,最大值
#与上同
tmp=[]
for id in range(1,11):
tmp.append(id**2) #可直接将平方追加到list
print(tmp)
#列表解析
foo=[id**2 for id in range(1,11)]
print(foo)
切片和复制列表
tmp = ['charles', 'martina', 'michael', 'florence', 'eli']
print(tmp[0:3]) #第1到第3个元素;[:3]也表示第1到第3个元素;[3:]表示第3到最后一个元素;[-2:]表示最后两个元素
foo=tmp[:] #复制列表,此时foo是tmp的拷贝
print(foo)
foo=tmp #这样是不行的
print(foo)
tmp.append("AAA")
print(tmp)
print(foo) #在tmp后面追加同样会出现在foo里面,因为foo=tmp将两个变量指向了同一个列
#通过for循环遍历切片
for id in tmp[0:3]:
print(id.title())
元组
不可变的列表称为元组 。虽然元组变量元素不能修改,但是可以给变量重新赋值。
tmp=(200,50)
print(tmp[0]) #通过索引号访问元组元素
print(tmp[1])
tmp[0]=111 #会报错,因为元组元素不可更改
tmp=(111,50) #给变量重新赋值
print(tmp)
第 5 章 if 语句
==、!=、>=、<=、>、<、and、or、
判断比较和检查
tmp=["audi","bmw","subaru","toyota"]
for id in tmp:
if id=='audi': #注意这里有冒号
print(id.title())
else: #注意这里有冒号
print(id.upper())
'audi' in tmp #检查某个值是否包含在列表中,会返回TRUE和FALSE; 若是 'audi' not in tmp 则检查某个值是否不包含在列表中
if 'aaa' not in tmp:
print("不包含!")
car = 'bmw'
if car == 'bmw': #通过==判断是否相等,!=判断是否不等,
print("干得好!")
检查多个条件
使用and 和or检查多个条件
age_0 = 22
age_1 = 18
age_0 >= 21 and age_1 >= 21 #等价于(age_0 >= 21) and (age_1 >= 21),加上括号提高可读性
if-else
tmp=17
if tmp >=18:
print("条件成立!")
else: # 在 IDLE 里该句最靠左边
print("条件不成立!")
if-elif-else
tmp=27
if tmp <= 4:
print("tmp不大于4")
elif tmp < 18:
print("tmp介于4和18之间")
else:
print("tmp大于等于18")
#可以有多个elif
age = 12
if age < 4:
price = 0
elif age < 18:
price = 5
elif age < 65:
price = 10
else: # Python不要求if-elif 结构后面必须有else 代码块,故该句可改成elif age >=65:
price = 5
print("Your admission cost is $" + str(price) + ".")
for循环里用if 和 if里面用for循环
tmp = ['mushrooms', 'green peppers', 'extra cheese']
for id in tmp:
if id == 'green peppers':
print("Sorry, we are out of green peppers right now.")
else:
print("Adding " + id + ".")
print("\nFinished making your pizza!")
确定列表非空
在if 语句中将列表名用在条件表达式中时, 列表非空时返回True ,空列表返回False。
tmp=[]
if tmp: #因为tmp是空列表,所以返回False,执行else
if 'aaa' in tmp:
print("aaa在里面")
else:
print("这他妈是个空的!")
确定一个列表中的元素是否存在于另一个列表
tmp = ['mushrooms', 'olives', 'green peppers',
'pepperoni', 'pineapple', 'extra cheese']
foo = ['mushrooms', 'french fries', 'extra cheese']
for id in foo:
if id in tmp:
print("Adding " + id + ".")
else:
print("Sorry, we don't have " + id + ".")
print("\nFinished making your pizza!")
第6章 字典
列表是[],元组是(),字典是{}
tmp = {'color': 'green', 'points': 5} #字典中存储的是键-值对,这个字典存储了两个键-值对。
print(tmp['color'])
print(tmp['points'])
创建、填充、访问、添加、修改、删除、遍历
tmp = {} #创建空字典
tmp['color'] = 'green' #填充空字典,[ ]里面是键,=右边是值
tmp['points'] = 5
print(tmp) # tmp = {'color': 'green', 'points': 5}
print(tmp['points']) # 访问字典中的值
tmp['bar'] = 0 #添加键-值对。键-值对在字典中的排列顺序不重要,但是键和值的对应关系重要
print(tmp)
tmp['color'] = 'yellow' #修改字典中的值
print(tmp)
del tmp['bar'] #删除键值对
print(tmp)
#遍历字典中所有键、值、键值对
for id,foo in tmp.items(): # for 键变量,值变量 in 字典.items(): ##遍历键值对的方式。
print("\nid:" + id)
print("foo:" + str(foo)) #若字典的值没有数字,foo这里不需要写str
for id in tmp.keys(): # 遍历键是将items换成keys;将tmp.keys()改成set(tmp.keys())可以去除重复,将set换成sorted可以排序。
print(id.title())
for id in tmp.values(): # 遍历值是将items换成values
print(str(id).title())
嵌套
在列表中嵌套字典
alien_0 = {'color': 'green', 'points': 5}
alien_1 = {'color': 'yellow', 'points': 10}
alien_2 = {'color': 'red', 'points': 15}
aliens = [alien_0, alien_1, alien_2]
for id in aliens:
print(id)
在字典中嵌套列表
当需要在字典中将一个键关联到多个值时, 可以在字典中嵌套一个列表。
alien = {'color': ['green', 'yellow', 'red'], 'points': [5,10,15]}
for id in alien['color']:
print(id)
在字典中嵌套字典
字典中嵌套字典要注意四个逗号,结构是 {键:{键:值,},键:{键:值,},}
users = {
'aeinstein': {
'first': 'albert',
'last': 'einstein',
'location': 'princeton', #注意这里的逗号
}, #注意这里的逗号
'mcurie': {
'first': 'marie',
'last': 'curie',
'location': 'paris', #注意这里的逗号
}, #注意这里的逗号
}
for id,foo in users.items():
print("\nUsername:" + " " +id)
print("\tFull name:" + " " + foo['first'].title() + " " + foo['last'].title())
print("\tLocation:" + " " + foo['location'].title())
第7章 用户输入和while 循环
input()
函数input() 可暂停程序,显示input()中的提示,等待用户输入。 可将用户输入存储在一个变量中,然后使用输入。
>>> id = input("Tell me your name: ") #等待用户输入文本,将其存储在变量中。
Tell me your name:Shuntai Yu
>>> print(id + " " + "is very hansome!") #使用输入
Shuntai Yu is very hansome!
同上
>>> tmp = "Tell me your name: "
>>> id = input(tmp)
Tell me your name: Shuntai Yu
>>> print(id + " " + "is very hansome!")
Shuntai Yu is very hansome!
#在提示中添加内容
>>> tmp = "Tell me your name"
>>> tmp += ",please! :" # +=可以在提示中添加新的内容。
>>> id = input(tmp)
Tell me your name,please! :Shuntai Yu
>>> print(id + " " + "is very hansome!")
Shuntai Yu is very hansome!
int()
python会将用户输入看做字符串,使用int()可以获得数值
>>> age = input("How old are you? ")
How old are you? 21
>>> age >= 18 #上面输入的数字会被认作字符串,所以这里会报错
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '>=' not supported between instances of 'str' and 'int'
>>> age = int(age) #转成数值
>>> age >= 18 #数值可以进行判断
True
%
%将两个数相除并返回余数:
>>> 4 % 3
1
while循环
一个思想很重要:while就是判断,若为逻辑运算则while后面的为True,就继续执行;若后面是列表字之类的,则非空就继续执行。所以while id就是判断id的逻辑值。
>>> id = 1
>>> while id <= 5: #while就是判断,while后面的为id <= 5,若为True就继续执行
... print(id) # 我是用的IDLE,注意该句前面tab键
... id += 1 #该句等于 id = id + 1
...
1
2
3
4
5
>>> id = True
>>> while id: # #while就是判断,while后面的为id,而id = True,所以会继续执行下面的代码。
print("Hello!")
break #若此处不break,则会产生无限循环。
#该例子没有停止运行while循环,所以会不停执行下去。终止它使用Ctrl + C。
id = False
while id ==False:
print("Hello!")
Hello!
Hello!
Hello!
.
.
.
tmp = ['a', 'b', 'c']
while tmp: # tmp为非空列表,故后面可以继续执行。
print('hello')
break
让用户选择何时退出
prompt = "\nTell me something, and I will repeat it back to you:"
prompt += "\nEnter 'quit' to end the program. " # 我的理解:这个+=可以理解为对上面定义的补充,因为上面已经对prompt进行了定义,这里表示再对定义进行追加内容。
message = ""
while message != 'quit': #若无可供比较的东西,程序无法继续运行,所以上面给message赋了空字符串。
message = input(prompt)
print(message)
#如果没有可供比较的东西, Python将无法继续运行程序。 为解决这个问题, 我们必须给变量message 指定一个初始值。 虽然这个初始值只是一个空字符串, 但符合要求, 让Python能够执行while 循环所需的比较。 只要message 的值不是'quit' , 这个循环就不断运行。首次遇到该循环时,message 是空字符串, 因此进入循环。
#下面这个也可以实现上面的效果
tmp = "\nTell me something, and I will repeat it back to you:"
tmp += "\nEnter 'quit' to end the program."
id = ''
while id != 'quit':
id=input(tmp)
#下面这个也可以实现上面的效果
tmp='\nTell me something, and I will repeat it back to you:'
foo="Enter 'quit' to end the program."
id=''
while id !='quit':
print(tmp)
id=input(foo)
#比较一下这三种实现方法。
标志
标志是程序的交通信号灯。 可以让程序在标志为True 时继续运行(当然也可以为False时继续运行,自己设置),这样, 在while 语句中只需检查标志的当前值是否为True ,并将所有测试都放在其他地方, 从而让程序更整洁。
prompt = "\nTell me something, and I will repeat it back to you:"
prompt += "\nEnter 'quit' to end the program. "
id = True
while id:
message = input(prompt)
if message == 'quit':
id = False
else:
print(message)
break 和 continue
break不再执行余下的代码,直接跳出循环。
continue忽略余下的代码,返回到循环开头。
>>> id = True
>>> while id: #以while True 打头的循环将不断运行, 直到遇到break 语句。
print("Hello!")
break
Hello!
#从1数到10只打印奇数
id = 0
while id < 10:
id += 1
if id % 2 == 0:
continue # continue忽略剩下的代码,返回到循环开头。
print(id)
使用while 循环来处理列表和字典
列表之间移动元素
只是遍历列表可使用for循环和while循环;
在遍历列表的同时又要对其进行修改,使用while 循环,不能用for循环。 通过将while 循环同列表和字典结合起来使用, 可收集、 存储并组织大量输入, 供以后查看和显示。
亲手打一下下面的例子!
# 首先,分别创建一个非空列表和空列表,将非空列表中处理后的元素移到空列表中。
tmp = ['alice', 'brian', 'candace']
foo = []
# 处理tmp中每个元素,并将处理过的元素移到foo中
while tmp:
arg = tmp.pop()
print("Verifying user: " + arg.title()) #这里的处理就是首写字母变成大写
foo.append(arg)
# 显示处理过的元素
print("\nconfirmed users:")
for arg in foo:
print(arg.title())
pets = ['cat','cat','cat','dog','dog','dog','rabbit']
print(pets)
pets.remove('cat') # .remove() 只能一次删除一个,想将pets里面的‘cat’全部删除需要使用循环。
print(pets)
while 'cat' in pets: # 使用循环可全部删除
pets.remove('cat')
print(pets)
使用用户输入填充字典
实现如下
What is your name? Eric
Which mountain would you like to climb someday? Denali
Would you like to let another person respond? (yes/ no) yes
What is your name? Lynn
Which mountain would you like to climb someday? Devil's Thumb
Would you like to let another person respond? (yes/ no) no
--- Poll Results ---
Lynn would like to climb Devil's Thumb.
Eric would like to climb Denali.
方法一:
responses = {}
polling_active = True # 设置一个标志, 指出调查是否继续
while polling_active:
name = input("\nWhat is your name? ")
response = input("Which mountain would you like to climb someday? ")
responses[name] = response # 将用户输入填充进字典
repeat = input("Would you like to let another person respond? (yes/ no) ")
if repeat == 'no': # 通过if来实现以用户输入来决定是否结束while循环
polling_active = False
print("\n--- Poll Results ---")
for name, response in responses.items():
print(name + " would like to climb " + response + ".")
方法二:
tmp = {}
name = input("what is your name? ")
mou = input("which mountain would you like to climb someday? ")
tmp[name] = mou
foo = input("Would you like to let another person respond? (yes/ no) ")
while foo =='yes':
name = input("what is your name? ")
mou = input("which mountain would you like to climb someday? ")
tmp[name] = mou
foo = input("Would you like to let another person respond? (yes/ no) ")
print("\n---poll results---")
for id,arg in tmp.items():
print(id + " would like to climb " + arg)
第8章 函数
定义函数
定义函数使用def,def是指definition的缩写
def 函数名(形参): #即使没有形参,()也不可少; 若多个形参,则用,间隔;
函数要执行的任务
def funct(id,fib,arg="rabbit"): # id和fib和arg是三个形参,即函数完成工作所需要的信息。并且形参可以指定默认值,arg就指定了默认值。
print("\nI have a " + id + ".")
print("My " + id + "'s name is " + fib.title() + ".")
print("My " + arg + "'s name is Jack .")
funct('dog', 'Lily') # 'dog'和 'Lily'是实参,即调用函数时传递给函数的信息,这种是位置实参,要求顺序和形参一致。arg没有新赋值,则使用默认值。
funct('dog', 'Lily','cat') #arg新赋值为'cat'所以弃默认值,使用新赋值。
funct(fib = 'Lily',id = 'dog', arg="cat") #这种是关键字实参,因为指定了形参名,所以不需要顺序一致。且对arg赋了新值,故使用新值。
# 位置实参、关键字实参和默认值可以混合使用
返回值
def funct(id,foo):
arg = id + ' ' + foo
return arg.title() # 函数中使用return将值返回到函数调用行
fib = funct('shuntai', 'yu') # 存储返回值需要提供变量
print(fib)
#函数可返回任何类型的值
def funct(first_name, last_name):
person = {'first': first_name, 'last': last_name}
return person #返回的是字典
musician = funct('jimi', 'hendrix')
print(musician)
让实参变成可选
def funct(first_name, middle_name, last_name):
full_name = first_name + ' ' + middle_name + ' ' + last_name
return full_name.title()
musician = funct('john', 'lee', 'hooker')
print(musician)
上面的例子适用于有中间名的名字,但不是所有人都有中间名,所以要让中间名的实参变得可选
def funct(first_name, last_name, middle_name=''): #先将中间名变成空字符串
if middle_name: # 进行判断,若中间名非空,后续执行;若中间名为空则执行else。
full_name = first_name + ' ' + middle_name + ' ' + last_name
else:
full_name = first_name + ' ' + last_name
return full_name.title()
musician = funct('jimi', 'hendrix')
print(musician)
musician = funct('john', 'hooker', 'lee')
print(musician)
结合使用函数和while循环
实现如下效果:
Please tell me your name:
enter 'q' at any time to quit
First name: eric
Last name: matthes
Hello, Eric Matthes
Please tell me your name:
enter 'q' at any time to quit
First name: q
方法1:
def funct(First_name,Last_name):
tmp = "\n" + "Hello, " + First_name + " " + Last_name + "!\n"
return tmp.title()
while True:
print("Please tell me your name:")
print("(" + "enter 'q' at any time to quit" + ")")
f_name = input("First name: ")
if f_name == 'q':
break
l_name = input("Last name: ")
if l_name == 'q':
break
foo = funct(f_name,l_name)
print(foo)
方法2:
def funct(first_name,last_name):
print("\nHello, " + f_name.title() + " " + l_name.title() + "!\n")
while True:
print("Please tell me your name:")
print("(" + "enter 'q' at any time to quit" + ")" )
f_name = input("First name: ")
if f_name =='q':
break
l_name = input("Last name: ")
if l_name =='q':
break
funct(f_name,l_name)
第7章 使用while 循环来处理列表和字典 那一个例子可以定义两个函数
tmp = ['alice', 'brian', 'candace']
foo = []
def funct_1(tmp,foo): #定义第一个函数
while tmp:
arg = tmp.pop()
print("Verifying user: " + arg.title()) #这里的处理就是首写字母变成大写
foo.append(arg)
def funct_2(foo): #定义第二个函数
print("\nconfirmed users:")
for arg in foo:
print(arg.title())
funct_1(tmp,foo) # 这个函数运行之后,tmp会变成空列表,若不想如此,则可以用tmp[:]替换tmp,即用tmp的副本作为函数的实参。
funct_2(foo)
print(tmp) # 可以看到tmp变空了
print(foo) #可以看到foo变满了
传递任意数量的实参
一个 * 创建空元组,两个 * 创建空字典。
空元组
在形参名前面加 * 可以创建一个空元组,该空元组可以将接收到的所有值都封装到这个元组中。
def funct(*foo):
print(foo)
funct('aaa')
funct('aaa', 'bbb', 'ccc')
当函数接受不同类型的实参,则星号实参要放在最后。python会先匹配位置实参和关键字实参,再将剩下的实参都收集进最后一个形参中。
def funct(size,*foo):
print("Making a " + str(size) + "-inch pizza with the following topppings:") # 数字要通过str() 转换
for id in foo:
print("-" + id)
funct(2,'aaa')
funct(5,'aaa', 'bbb', 'ccc') #先匹配位置实参5,再将剩下的实参都收集进最后一个形参中。
空字典
有时候, 需要接受任意数量的实参, 但预先不知道传递给函数的会是什么样的信息。 在这种情况下, 可创建空字典。
def build_profile(first, last, **user_info): # 两个星号创建一个名为user_info 的空字典, 并将收到的所有名称—值对都封装到这个字典中。
#创建字典并将非星实参填充进字典
profile = {}
profile['first_name'] = first
profile['last_name'] = last
for key, value in user_info.items(): #遍历星号实参键-值对
profile[key] = value # 也填充进同一字典
return profile #将非星实参和星号实参填充好的字典返回给函数调用行
user_profile = build_profile('albert', 'einstein',
location='princeton',
field='physics')
print(user_profile)
#调用这个函数时, 不管额外提供了多少个键—值对, 它都能正确地处理。
将函数存储在模块
类似于shell中的创建函数库。只需编写一条import 语句并在其中指定模块名, 就可在程序中使用该模块中的所有函数。
例子1
下面这个例子使用jupyter无法展示,可用vs code。
创建模块
创建一个 .py 为后缀的文件,可在该文件中定义很多函数,该文件称为模块
pizza.py
def funct(size, *toppings):
print("\nMaking a " + str(size) + "-inch pizza with the following toppings:")
for topping in toppings:
print("- " + topping)
读取模块
读取模块则调用函数时需要带上模块名,读取模块中函数则调用函数时不需要带上模块名。
pizza.py文件同一目录下新建making_pizzas.py文件
读取所有函数
making_pizzas.py
import pizza # 读取模块,此时模块中所有函数都可调用。读取方法: import 模块名
#import pizza as pp # 可以给模块指定别名,若这里指定别名,下面也要改
pizza.funct(16, 'pepperoni') # 调用模块中的函数,需要带上模块名,方法: 模块名.函数名()
pizza.funct(12, 'mushrooms', 'green peppers', 'extra cheese')
读取特定函数
from pizza import funct # 读取模块中特定函数
from pizza import * # 读取模块中所有函数,下面调用函数时也不用带上模块名。但这种方法极不推荐,可能会导致灾难性后果。
#from pizza import funct as tmp # 当函数名太长或者与当前程序中的一些变量名冲突时则使用as为函数指定别名,这里指定funct的别名为tmp
funct(16, 'pepperoni') # 调用模块中的函数不需要带上模块名,方法: 模块名.函数名() #若上面为别名,这里也要为别名
funct(12, 'mushrooms', 'green peppers', 'extra cheese')
第9章 类
编写类时, 定义一大类对象都有的通用行为。 基于类创建对象时, 每个对象都自动具备这种通用行为, 然后可根据需要赋予每个对象独特的个性。 根据类来创建对象被称为实例化,这让你可以使用类的实例。
9.1创建和使用类
#创建一个表示小狗的类Dog (它表示的不是特定的小狗,而是小狗这一类)
# Dog类包含 名字和年龄 + 蹲下和打滚。
#然后通过编写好的类去创建特定小狗的实例。
#创建Dog实例时,通过实参向Dog()传递名字和年龄,self会自动传递。
#类中的函数称为方法
class Dog(): # 定义类: class 类名(首字母大写)():
def __init__(self, name, age): #定义名字和年龄。 注意init开头和末尾各两个下划线。 形参self一定要有,并且要在其它形参前面。 __init__接受形参的值,并将它们存储在根据该类创建的实例属性中。
self.name = name # (鄙人愚见:通过添加self前缀将对应的实参加进属性,这里可以改成self.tmp = name,但是后面使用self.name的地方要对应为self.tmp,对应的都是形参name,只不过在属性中一个命名为了name,一个命名为了tmp,类中其它方法使用时后续调用)。以self为前缀的变量可以供类中所有方法使用。 这一步目的是获取存储在形参name中的值,并将其存储到变量name中,然后该变量被关联到当前创建的实例。
self.age = age #也可改成 self.foo = age,但是后续调用时要使用self.foo而不能再使用self.age
def sit(self): #定义蹲下,只有形参self,则后面创建的实例都能访问该方法
print(self.name.title() + " is now sitting.")
def roll_over(self): #定义打滚
print(self.name.title() + " rolled over!")
#创建实例
#访问属性和调用方法的办法就是: 实例名.属性名/方法名()
## 访问属性
### 访问属性的办法: 实例名.属性名
my_dog = Dog('willie',6) # 使用前面编写好的Dog类创建实例,取名为my_dog;让python创建一个名字为Willie,年龄为6的小狗,self不需要给
print("My dog's name is " + my_dog.name.title() + ".") #句点法访问属性
print("My dog is " + str(my_dog.age) + " years old.")
your_dog = Dog('lucy', 3) #可以创建多个实例,这是另一个实例
print("\nYour dog's name is " + your_dog.name.title() + ".")
print("Your dog is " + str(your_dog.age) + " years old.")
## 调用方法(使用句点法调用类中定义的任何方法(函数))
### 调用方法的办法: 实例名.方法名
my_dog.sit()
my_dog.roll_over()
your_dog.sit()
your_dog.roll_over()
9.2使用类和实例
class Car():
def __init__(self, make, model, year): #方法__init__() 接受这些形参的值, 并将它们存储在根据这个类创建的实例的属性中。
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.")
#################################### 代码1 #######################################
#以上部分代码简称 代码1,下面会用到。
my_new_car = Car('audi', 'a4', 2016) #创建实例 my_new_car; 给出三个实参,self不用给。
print(my_new_car.get_descriptive_name()) #访问属性
my_new_car.read_odometer() #调用方法
9.2.3修改属性的值
直接修改
# 代码1
my_new_car.odometer_reading = 23
my_new_car.read_odometer()
通过方法修改
(即通过定义新的函数修改)
# 代码1
def update_odometer(self, mileage):
self.odometer_reading = mileage # 此处直接接受参数
my_new_car = Car('audi', 'a4', 2016)
my_new_car.update_odometer(23) # 通过向新定义的方法 update_odometer传递参数来修改
my_new_car.read_odometer()
# 通过在方法 update_odometer 里面添加 if 来禁止往回调里程表读数
# 代码1
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)
my_new_car.update_odometer(23)
my_new_car.read_odometer()
9.3 继承
继承五步骤:
1)括号中指定父类名称
2)初始化父类属性
3)super()关联父子
4)添加新属性
5)添加描述新属性的方法
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
#继承五步骤
class ElectricCar(Car): #步骤1:括号中指定父类名称
def __init__(self, make, model, year): #步骤2:初始化父类属性
super().__init__(make, model, year) #步骤3:super()关联父子
self.battery_size = 70 #步骤4:添加新属性
def describe_battery(self): #步骤5:添加描述新属性的方法
print("This car has a " + str(self.battery_size) + "-kWh battery.")
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()
9.3.4重写父类的方法 和 9.3.5将实例用作属性看书
第10章 文件和异常
读取文件
文件名为 pi_digits.txt,文件的保存路径为D:\python_work\text_files,文件内容如下
3.1415926535
8979323846
2643383279
file_path = 'D:/python_work/text_files/pi_digits.txt' #指定绝对路径,但是要将\换成/
with open(file_path) as file_object: # with open as结构; with可以在不需要访问文件后将其关闭; open(文件名) 可以打开文件
contents = file_object.read() # 方法read()读取该文件全部内容并存储在contents中
print(contents.rstrip()) #打印。 不加 .rstrip()发现会有一个空行,加了之后可以删除字符串末尾的空白
#open()是函数,read()是方法。
遍历
file_path = 'D:/python_work/text_files/pi_digits.txt'
with open(file_path) as file_object:
for id in file_object:
print(id.rstrip()) # 如果是用print(id)则每一行下会有一个空行,用.rstrip()可以去除空行。
# 同上
file_path = 'D:/python_work/text_files/pi_digits.txt'
with open(file_path) as file_object:
lines = file_object.readlines()
for id in lines:
print(id.rstrip())
file_path = 'D:/python_work/text_files/pi_digits.txt'
with open(file_path) as file_object:
lines = file_object.readlines()
pi_string = ''
for id in lines:
pi_string += id.rstrip()
print(pi_string)
print(pi_string[:9] + "...") # 指定显示的字符数
print(len(pi_string))
tmp = input("Please enter your number: ")
if tmp in pi_string:
print("Yes!")
else:
print("No!")
写入文件
tmp = "programming.txt"
with open(tmp, 'w') as id: # open有3个实参,r(读取)、w(写入)、a(附加);若省略实参,则默认为读取。换成r和a试一下,以w模式打开文件一定小心,若文件本身有内容,则会被清空。
id.write("I love programming.\n") # 换行符可以换行
id.write("I love creating new games.") # 写入多句则多次使用 .write()
异常
print(5/0) # 会发生报错,显示Traceback
使用try-except,当try无异常则执行try下的,跳过except;若异常与except后的异常匹配,则继续运行
try:
print(5/0)
except ZeroDivisionError:
print("You can't divyexcee by zero!")
实现如下效果:
Give me two numbers, and I'll divide them.
Enter 'q' to quit.
First number: 5
Second number: 0
You can't divide by 0!
First number: 5
Second number: 2
2.5
First number: q
print("Give me two numbers, and I'll divide them.")
print("Enter 'q' to quit.")
while True:
first_number = input("\nFirst number: ")
if first_number == 'q':
break
second_number = input("Second number: ")
try:
answer = int(first_number) / int(second_number) # 可能引发异常的代码放try里面
except ZeroDivisionError: #except 代码块告诉Python, 如果它尝试运行try 代码块中的代码时引发了指定的异常, 该怎么办。
print("You can't divide by 0!")
else: # 若try代码成功执行,则执行else
print(answer)
# 下面这个是错的,想想错在哪里了?很有趣!
print("Give me two numcers, and I'll divide them.")
print("Enter 'q' to quit.")
while True:
f_number = input("First number: ")
if f_number == 'q':
break
s_number = input("Second number: ")
answer = int(f_number)/int(s_number)
try:
print(answer)
except ZeroDivisionError:
print("You can't divide by 0!")
#可能引发异常的代码才需要放在try语句中 answer = int(first_number) / int(second_number)可能异常
文本统计字数
def funct(file_name):
try:
with open(file_name, 'r') as tmp: # with open as结构
foo = tmp.read() # 方法read()读取该文件全部内容并存储在foo中
except FileNotFoundError:
print(file_name + " does not exist!") # 若这里改成 pass 则失败时一声不吭,不显示任何消息。
else:
fib = foo.split() # split()以空格为分隔符将字符串拆分,并存储进一个列表
num_words = len(fib)
print("The file " + file_name + " has about " + str(num_words) + " words.")
filename = ["pi_digits.txt","pi_million_didits.txt","programming.txt"] # 通过for循环遍历文件名
for id in filename:
funct(id)
10.4 存储数据
json.dump() 和 json.load()
三步骤
- 导模
- with open as
- json.dump() / json.load() 。json.dump() 接受两个实参,要被存储的数据和可用于存储的文件对象,json.load()接受一个实参,即要读取的对象。注意一点,不管是dump还是load都需要的是对象!也就是as后面那个东西,别写错了。
json.dump()是进行存储
import json #导入模块json
numbers = [2, 3, 5, 7, 11, 13]
#filename = 'tmp.json' # tmp.json只是随便取的名字
with open('tmp.json', 'w') as foo: # 以w模式打开tmp.json文件(json此时可以将数据写入, tmp.json只是随便取的名字),然后生成一个可用于存储数据的文件对象,并将该对象取名为 foo
json.dump(numbers,foo) # json.dump() 将numbers写入foo中
**json.load() **是进行读取
import json
with open('tmp.json','r') as foo: # 以r模式打开tmp.json文件
arg = json.load(foo) #不管是dump还是load都需要的是对象!也就是as后面那个东西,别写错了。
print(arg)
写代码实现如下功能:
若以前存储了用户名就加载它,否则提示用户输入用户名并存储它。
import json
filename = 'name.json'
try:
with open(filename) as f_obj:
username = json.load(f_obj) #不管是dump还是load都需要的是对象!也就是as后面那个东西,别写错了。
except FileNotFoundError:
arg = input("what is your name: ")
with open(filename,'w') as f_obj:
json.dump(arg,f_obj) # 不管是dump还是load都需要的是对象!也就是as后面那个东西,别写错了。
print("we will remember you when you come back " + arg)
else:
print("welcome back " + username)
10.43的重构看书
第11章 测试代码
使用Python模块unittest 中的工具来测试代码。
单元测试框架
测试函数
name_function.py
def funct(firstname,lastname): #定义一个方法
fullname = firstname + ' ' + lastname
return fullname.title()
names.py
from name_function import funct #从文件中导入方法
print("Enter 'q' at any time to quit.")
while True:
firstname = input("Please give me a firstname: ")
if firstname == 'q':
break
lastname = input("Please give me a lastname: ")
if lastname == 'q':
break
fullname = funct(firstname,lastname)
print(" \tNeatly formatted name: " + fullname + '.')
测试类
第15章 生成数据
matplotlib安装
win + s # 打开 cmd 命令行窗口
pip install wheel # 安装wheel
wheel # 查看wheel是否安装成功
pip wheel PyTZ
pip install pyparsing==1.5.6 --upgrade --user
pip install --user matplotlib
使用matplotlib来画图
matplotlib官网
python -m pip install matplotlib
# 或者 pip install matplotlib
import matplotlib.pyplot as tmp # 从matplotlib里面导入pyplot模块
foo = [1,4,9,16,25] # 创建列表
tmp.plot(foo) # 将列表传递给函数plot
tmp.show() # 显示图形
# 在cmd里面直接输入jupyter notebook,即可使用jupyter notebook。将上述代码复制进它也能画图。
图片修改
plot.py
iimport matplotlib.pyplot as tmp #导入模块并指定别名
arg = [1,2,3,4,5,6,7,8,9,10] # 同 arg =list(range(1,11))
foo = [1,4,9,16,25,36,49,64,81,100] # 同 foo = [x**2 for x in arg] 从而实现自动计算
# tmp.plot(arg,foo,linewidth=6) #arg和foo的位置顺序对应了xy轴
tmp.scatter(arg,foo,s=200, edgecolor='none',c='red', cmap=tmp.cm.Blues)
#.scatter()就是点图; s为点尺寸; edgecolor是点轮廓色,none-没有轮廓;
#c是点填充色,c也可改成color #RGB颜色模式: c=(0,0.2,0.4,0.6,1.0),越接近1颜色越浅,越接近0越深。#颜色映射: c=foo;
#cmap 告诉pyplot使用哪个颜色映射。Blues可换成Reds或者Greens试试(别忘了后面的s)。要了解pyplot 中所有的颜色映射, 请访问http://matplotlib.org/ , 单击Examples, 向下滚动到Color Examples,再单击colormaps_reference。
#添加title和x、y轴坐标
tmp.title("Title",fontsize=11)
tmp.xlabel("xlabel",fontsize= 22)
tmp.ylabel("ylabel", fontsize = 33)
tmp.tick_params(axis='both',which='major', labelsize = 10) # 设置刻度标记的大小;which有3个刻度,major(主刻度线)、minor(副刻度线)、both
tmp.axis([0,15,1,108]) # 设置坐标轴取值范围
tmp.show() #可替换成 tmp.savefig('C:/Users/HASEE/Desktop/tmp.png', bbox_inches='tight') # 使用 别名.savefig()存储图片,指定路径;若不指定路径,则会保存在plot.py相同目录下;bbox_inches='tight'是剪掉图片空白位置,省略此参数则保留空白位置。
15.3 随机漫步
首先理解 randint 和 choice
#下面两个例子都是在1,2,3之间任意选择一个数赋值给左边
from random import randint
tmp = randint(1,3) # randint(a,b)表示获取1到3之间的任何数,包括1和3
print(tmp)
from random import choice
tmp = choice([1,2,3]) #choice(1,3)表示获取1到3之间的任何数,包括1和3
print(tmp)
ramdom_walk.py
from random import choice
class RandomWalk():
def __init__(self,num_points=5000): # __init__接受形参的值,并将它们存储在根据该类创建的实例属性中。
self.n_p = num_points # 以self为前缀的变量可以供类中所有方法使用。 这一步目的是获取存储在形参num_points中的值,并将其存储到变量num_points中,然后该变量被关联到当前创建的实例。
self.x_values = [0]
self.y_values = [0]
def fill_walk(self): #定义新方法,只有形参self,则后面创建的实例都能访问该方法
while len(self.x_values) < self.n_p:
x_direction = choice([1,-1]) # 从[]里面随机取一个值赋给左边
x_distance = choice([0,1,2,3,4])
x_step = x_direction * x_distance
y_direction = choice([1,-1])
y_distance = choice([0,1,2,3,4])
y_step = y_direction * y_distance
if x_step == 0 and y_step == 0:
continue
next_x = self.x_values[-1] + x_step
next_y = self.y_values[-1] + y_step
self.x_values.append(next_x)
self.y_values.append(next_y)
rw_visual.py,运行该代码可见随机漫步图
import matplotlib.pyplot as plt
from ramdom_walk import RandomWalk
rw = RandomWalk()
rw.fill_walk()
plt.scatter(rw.x_values,rw.y_values,s=15)
plt.show()
将rw_visual.py代码改成如下,则关闭查看器之后输入y可模拟多次随机漫步,并且对图片进行了修饰
import matplotlib.pyplot as plt
from ramdom_walk import RandomWalk
while True:
rw = RandomWalk() #在()里面加入50000则可以将点数变成50000
rw.fill_walk()
#调整图片宽、高、分辨率、背景色(若略则有默认尺寸)
plt.figure(figsize=(10,10),dpi=128,facecolor='gray',edgecolor='red') #.figure()可实现图片调整。dpi是分辨率;facecolor是背景色;edgecolor是画板边框颜色;
#给点着色(若略则有默认色)
n_p = list(range(rw.n_p))
plt.scatter(rw.x_values,rw.y_values,c=n_p,cmap = plt.cm.Reds,edgecolor = 'none', s=15)
#重绘起/终点(若略则起/终点大小颜色与其它点无异)
plt.scatter(0,0,c='green',edgecolor = 'none', s=100) #重新绘制起点,使之明显
plt.scatter(rw.x_values[-1],rw.y_values[-1],c='red',edgecolor = 'none', s=200) #重新绘制终点,使之明显
#隐藏坐标轴(若略则有坐标轴)
plt.axes().get_xaxis().set_visible(False) #改False为True有坐标轴
plt.axes().get_yaxis().set_visible(False)
plt.show()
#多次随机漫步
keep_running = input("Make another walk? (y/n):")
if keep_running == 'n':
break
15.4 使用Pygal模拟掷骰子
访问http://www.pygal.org/ , 单击Documentation, 再单击Chart types。 可看到各种图表且每个示例都有源代码。
安装pygal
pip install pygal
die.py
from random import randint
class Die():
def __init__(self, num_sides=6):
self.num_sides = num_sides
def roll(self):
return randint(1, self.num_sides)
die_visual.py
from die import Die
# 创建实例
die_1 = Die() # 创建一个6面的骰子,因为默认为6
die_2 = Die(10) # 创建一个10面的骰子
#上面两个可修改为 die_1,die_2 = [],[] 这也是创建两个空列表的方法
# 掷骰子
results = [] # 创建空列表
for roll_num in range(50000): #使用for循环来掷骰子100次
result = die_1.roll() + die_2.roll() #使用for循环来掷骰子100次
results.append(result) #将result追加到列表results中
print(results)
# 分析结果
frequencies = []
for value in range(2,die_1.num_sides + die_2.num_sides +1):
frequency = results.count(value) #列表.count(value) 表示计算列表中value有几个
frequencies.append(frequency) #将frequency追加到列表frequencies中
print(frequencies)
# 对结果进行可视化
import pygal
hist = pygal.Bar() # 创建实例并存储在hist中
hist.title = "Results of rolling a D6 and D10 50000 times."
hist.x_labels = [ '2', '3', '4', '5', '6','7','8','9','10','11','12','13','14','15','16'] # .x_labels是添加横刻度值
hist.x_title = "Result" # .x_title是添加横标题
hist.y_title = "Frequency of Result" # .x_title是添加横标题
hist.add('D6 + D10', frequencies) # 将frequencies中一系列的值添加到图表中,这些值的标签是D6。
hist.render_to_file('C:/Users/HASEE/Desktop/die_visual.svg') # 将图保存并命名 die_visual.svg,指定路径,若不指定路径则图和该代码所在文件位于同一文件夹下。
import csv #csv包含在python标椎库中
from datetime import datetime #模块中导入类
filename = 'C:/Users/HASEE/Desktop/sitka_weather_07-2014.csv' # csv文件以逗号分割;将sitka_weather_07-2014.csv换成sitka_weather_2014.csv可绘制全年
with open(filename) as f: #打开文件
reader = csv.reader(f) #读取文件
header_row = next(reader) #返回第一行
#print(header_row)
#for tmp,foo in enumerate(header_row): #enumerate可获取列表中每个元素的索引及其值
# print(tmp,foo)
#提取并读取数据
arg,highs,dates = [],[],[] #创建两个空列表,一个用来存贮字符串,另一个存储数字。
#arg = [] #再创建空列表等会儿存贮数字
for row in reader: #遍历行; #reader就是对象(object);row是对象每行;row[1]表示对象每行第二列,若为-1则为最后一列;
highs.append(row[1]) #将每行第二个值追加到列表highs里面。
foo = int(row[1]) #int()将字符串转成数字
arg.append(foo) #将数字追加到列表arg里面
#在图表中添加日期
current_date = datetime.strptime(row[0], "%Y-%m-%d") # 第一个实参是row[0],是对象每行第一列(日期);第二个实参告诉python如何设置日期格式。
dates.append(current_date)
print(highs)
print(arg)
#根据数据绘制图形
from matplotlib import pyplot as plt
fig = plt.figure(dpi = 128, figsize = (10,6))
plt.plot(arg,c= 'red')
plt.plot(dates,arg,c='red')
#设置图形格式
fig.autofmt_xdate() #绘制斜日期标签,避免重叠
plt.title("aaa",fontsize=36,c='pink')
plt.xlabel("x label",fontsize = 36,c='pink')
plt.ylabel("y label",fontsize = 36,c='pink')
plt.tick_params(axis='both',which='both',labelsize=16)# 设置刻度标记的大小;which有3个刻度,major(主刻度线)、minor(副刻度线)、both
plt.axis([0,40,30,100]) # 设置坐标轴取值范围
plt.show()
16.1.7
import csv #csv包含在python标椎库中
from datetime import datetime #模块中导入类
filename = 'C:/Users/HASEE/Desktop/sitka_weather_2014.csv' # csv文件以逗号分割;将sitka_weather_07-2014.csv换成sitka_weather_2014.csv可绘制全年
with open(filename) as f: #打开文件
reader = csv.reader(f) #读取文件
header_row = next(reader) #返回第一行
#提取并读取数据
highs,dates = [],[] #创建两个空列表,一个用来存贮字符串,另一个存储数字。
for row in reader: #遍历行; #reader就是对象(object);row是对象每行;row[1]表示对象每行第二列,若为-1则为最后一列;
current_date = datetime.strptime(row[0], "%Y-%m-%d") # 第一个实参是row[0],是对象每行第一列(日期);第二个实参告诉python如何设置日期格式。
dates.append(current_date)
high = int(row[1]) #int()将字符串转成数字
highs.append(high) #将数字追加到列表arg里面
#根据数据绘制图形
from matplotlib import pyplot as plt
fig = plt.figure(dpi = 128, figsize = (10,6))
plt.plot(dates,highs,c='red')
#设置图形格式
fig.autofmt_xdate() #绘制斜日期标签,避免重叠
plt.title("aaa",fontsize=36,c='pink')
plt.xlabel("x label",fontsize = 36,c='pink')
plt.ylabel("y label",fontsize = 36,c='pink')
plt.tick_params(axis='both',which='both',labelsize=16)# 设置刻度标记的大小;which有3个刻度,major(主刻度线)、minor(副刻度线)、both
plt.show()
16.1.9
import csv #csv包含在python标椎库中
from datetime import datetime #模块中导入类
filename = 'C:/Users/HASEE/Desktop/sitka_weather_2014.csv' # csv文件以逗号分割;将sitka_weather_07-2014.csv换成sitka_weather_2014.csv可绘制全年
with open(filename) as f: #打开文件
reader = csv.reader(f) #读取文件
header_row = next(reader) #返回第一行
#提取并读取数据
highs,lows,dates = [],[],[] #创建两个空列表,一个用来存贮字符串,另一个存储数字。
for row in reader: #遍历行; #reader就是对象(object);row是对象每行;row[1]表示对象每行第二列,若为-1则为最后一列;很多数据集都可能缺失数据、 数据格式不正确或数据本身不正确。 此时可使用 try-exceptelse 代码块来处理数据缺失的问题。 有时使用continue 跳过一些数据, 或者remove() 或del 将已提取的数据删除。
current_date = datetime.strptime(row[0], "%Y-%m-%d") # 第一个实参是row[0],是对象每行第一列(日期);第二个实参告诉python如何设置日期格式。
dates.append(current_date)
high = int(row[1]) #int()将字符串转成数字
highs.append(high) #将数字追加到列表arg里面
low = int(row[3]) #每行的第四列是最低气溫
lows.append(low)
#根据数据绘制图形
from matplotlib import pyplot as plt
fig = plt.figure(dpi = 128, figsize = (10,6))
plt.plot(dates,highs,c='red',alpha=0.5) # 根据日期对最高气温画图;alpha表示透明度,1完全不透明(默认),0完全透明。
plt.plot(dates,lows,c='blue',alpha=0.5) # 根据日期对最低气温画图
plt.fill_between(dates,highs,lows,facecolor='blue',alpha=0.1) #填充两条线之间的区域,dates对应两个y值,将之间的区域填充。
#设置图形格式
fig.autofmt_xdate() #绘制斜日期标签,避免重叠
plt.title("aaa",fontsize=36,c='pink')
plt.xlabel("x label",fontsize = 36,c='pink')
plt.ylabel("y label",fontsize = 36,c='pink')
plt.tick_params(axis='both',which='both',labelsize=16)# 设置刻度标记的大小;which有3个刻度,major(主刻度线)、minor(副刻度线)、both
plt.show()
16.2