超级秘籍 | 纯文本--Python从入门到精通

点个赞吧

Python

 从零基础到入门

⊙Toy’s World
注意:学习前请先按照『附录α』的方法搭建环境
第一章 注释和变量

1.1 注释
单行注释(数字代表行数,不必关注): 官方网站

内容

多行注释:
“””
内容
““”

用三个单引号或三个双引号包裹

小练习:

这是不是一条注释?# _____(选填”是”或”不是”)。

1.2 变量
变量数据类型:
基本:
str(字符串) tuple(元祖) list(列表) dictionary(字典) set(集合) int(整数) float(浮点) complex(复数)
bool(布尔):
true(真) false(假)
变量赋值:变量名=赋值内容
例1:
a = 2 #整数
z = ”dk” #字符串

变量类型检测:(变量名) 返回
或:isinstance(变量名,预测的变量类型) 若符合,返回true 反之亦然
例2:
m = 1
type(m)
isinstance(m,int)

返回:

true
小练习:
已知变量k,isinstance(m,int)结果为false。则k不可能的数据类型是______。

1.3 变量命名规则
不可以使用关键字,不得以数字开头,不得含有空格,不得含有特殊符号,不得全部为数字。

小练习:
判断下列变量名是否合规。
Myf( ) 1Dt( ) window.height( ) m1t4a( ) China gdp ( ) fa_van ( )
1.4 关键字
关键字的获取:
import keyword
keyword kwlist
即可列出关键字。
关键字:

and elif import return class
as else in try
assert except is while
break finally lambda with
class for not yield
continue from or TRUE
def global pass FALSE
del if raise nonlocal
第二章 运算符
2.1 赋值运算符(=)
使用格式 将要赋值的变量=赋值目标
例3:
a = 1
b = "我是faq"
print(a,b)

则输出:
1我是faq
原理:把”faq”这个字符串交给了b这个变量存储,把1这个整数交给了a这个变量存储。
小练习:
A = 1
B = 2
A = B
B = A
现在请问B是__________。
2.2 算数运算符
2.2.1 算数加(+)
如果加号的两边是数(int)(float)(complex)则进行数学运算
如果加号的两边是字符串(str)则将字符串相加
例4:
a=1
b=2
print(a+b)
则输出结果:
3
错误示范:
a="1"
b="2"
print(a+b)
则输出结果:
12
这这里敬告大家,写程序时一定要注意数据类型!
小练习:
如果加号的两边是____(____)(____)(______)则进行数学运算。
如果加号的两边是____(____)则将____相加。
2.2.2 算数乘(星号)
如果乘号的两边是数(int)(float)(complex)则进行数学运算
注意:乘号可以做重复符号
例5:
print("%"5) #就是打印五个""
则输出结果:
%%%%%
小练习:
输出300个”+”
2.2.3 算数减(-)
此块内容没什么好讲的,只做算数运算符
例6:
i = 2
t = 3
f = t - i
print(f)
输出:
1
小练习:
A = 8
B = 3
C = A+B-C
现在,C的值为__________。还是会报错?如果报错,原因是什么?


2.2.4 算数除(/)
此块内容没什么好讲的,只做算数运算符
例7:
i = 2
t = 3
f = t / i
print(f)
输出:
1.5

2.2.5 向下取整(//)
可以理解为四舍五入中的"四舍",即小数点后无论是什么,都将原数变为不含小数的数。
例8:
a=10
b=3
print(a//b)
则输出结果:
3
2.2.6 取余(%%)
取余,顾名思义,就是取除不尽的数的余数。
就像我们小学学的一样
例9:10 ÷ 3 = 3……1
a=10
b=3
print(a%%b)
则输出结果:
1
python中的负数取余公式
r=(b-a)×(b//a)

2.2.7 算数幂()
例10:
i=2
t=3
f=t
i
print(f) #此程序相当于求3²
输出:
9
本节综合练习:
请用户输入两个数。
然后输出这两个数的各种运算结果(输入和输出请参考第三章)。

2.3 逻辑运算符
等于(==) 不等于(!=) 大于(>) 小于(<) 大于等于(>=) 小于等于(<=)
调用格式:数值一 运算符 数值二
匹配返回true 否则返回false
例11:
a = 1 == 2 #判断1是否等于2,并将结果返回到a中
print(a)
输出:
false
后边我们学到函数的时候就容易理解了:
def switc():
a = i == 2
return(a)
2.4 复合赋值运算符
原理:Python是从右到左执行的:
例12:
a+=2 # a=a+2
b/=5 # b=b/5
本章综合练习(共100分)
1.利用Python,使用变量的方法计算一个世纪有多少秒。(20分)

  1.                                                                        请用户输入n,a,b,求式子的值。(20分)
    

3.一次函数的解析式为y = kx + b,自主探究print()函数的使用方法,请用户输入k,b,输出这个解析式。(20分)
4.使用Python,解二元一次方程组 (20分)
5.利用Python,将弧度制转化为角度制(20分)。
提示(π可以用以下方式获取):
import math
变量 = math.pi
(如果不会做,可留到学完分支和循环之后做)
第三章 输入和输出
3.1 输出:print()函数
语法:print(“objects”,sep=““,end=“\n”,file=sys.stdout,flash=false)
其中:objects代表你要输出的内容 sep代表分隔符 end代表结束符,file代表输出流 flash代表是否强制刷新到输出流
注:\n代表换行符,如果添加了sep的值,那么每个输出之间都会用sep的参数分开。
例13:
print(”我是faq”)
输出:
我是faq
例14:
print(“我”,”是”,”fa”,q”,sep = “!”)
输出:
我!是!fa!q

例15:
print(“hello”,"world",end = ““,sep = ““)
print(“hello”,"world",end = “\n”,sep = ““)
输出:
hello world
hello
world
例16:
a = “我是faq”
print(a)
输出:
我是faq
例17:
a = “%”
print(a*10)
输出:
%%%%%%%%%%%
file 和 flash 以后会学到
小练习:
(1) 输出:中!国!是!我!们!伟!大!的!祖!国!
(2) 输出:C:\users\administrator\desktop\study\1.avi
(3) 输出:200个

3.2 输入:input()函数
语法:input([prompt])
prompt:提示符 由键盘输入,就是你往程序里输入的东西,也就是提示你应该输入什么。
注:如果不是字符串的话,最后先进行强制数据类型转换。
输入:x=数据类型(input([prompt]))
例18(一个简单的加法计算器):
x1=int(input(“请输入第一个数”))
x2=int(input(“请输入第二个数”))
y=x1+x2
print(“结果是”,y)
运行:
接着再来一次:
我滴个天怎么一言不合就报错了?
别急,让我们分析一下。错误类型是”ValueError”也就数据类型错误。怪不得呢,Python是容不得一个整数和一个小数以整数类型相加的。
修改代码为:
x1=float(input(“请输入第一个数”))
x2=float(input(“请输入第二个数”))
y=x1+x2
print(“结果是”,y)
要不然我干嘛要告诉你们必须进行强制数据类型转换......
觉得Python太难了?让我们再看看C语言:
再看一下C++:
反观C#:
所以说,不要身在福中不知福了吧[doge] 。
(这个写程序的在作秀,这一个小小程序连泛型接口都来了)
综合测试:
用Python写一个四则运算器(可以不让用户选择哪种运算)

第四章 让机器学会逻辑
友情提示:学会这一章,你就可以独立制作文字游戏了。
4.1 简单的if…else语句
if……else 语句语法:
if 条件(条件语句缩进一个tab,if与条件之后空一格):
满足条件时要做的事情
else:
条件不满足时要做的事情
例19 单次猜数字游戏:
num=8
number=int(input("输入你要猜的数字"))
if num=number
print("恭喜,答对了")
else:
print("错了")

小练习:
让用户输入今天是星期几,然后输出是否为工作日。

4.2 if单独语句
if单独语句语法:
if 条件语句:
条件满足时要做的事情

空一行以跳出if如果真语句#

接下来要做的事
例20:看不看电影
jiaban=false
if not jiaban
print("出去看电影")

print("回家睡觉")
4.3 if…elif(else if)…else语句
if…elif…else语句语法:
if 第一个条件:
执行满足第一个条件所执行的内容
elif 第二个条件:
执行满足第二个条件所执行的内容
elif 第n个条件:
执行满足第n个条件所执行的内容
else:
以上条件全不满足所执行的内容
例21:做一个等级判断器:

!/usr/bin/python #(说明python解释器)

coding:utf-8 #(采用中文编码)

point=int(input("请输入你的分数"))
if point>=90:
print("你的等级是A")
elif point>=75:
print("你的等级是B")
elif point>=60:
print("你的等级是C")
else:
print("恭喜你,不及格")
例 22:一个简单的文字游戏:

!/usr/bin/python #(说明python解释器)

coding:utf-8 #(采用中文编码)

lv = 1
print("冒险者你好!你现在一级了。")
q1 = input("你遇到了一只9级的野生刘宗恺,请问要不要攻击?(Y/N)")
if q1 = "Y":
print("由于刘宗恺太强大,你被打死了。")
elif q1 = "N":
print("你绕过了刘宗恺,继续往前走。")
...
else:
print("谁叫你乱输的?你死了")
4.4 三目运算符
这里给你个例子,自己琢磨吧
例23:计算绝对值
abs(text1.text)
不好意思,写错语言了。

x=int(input("请输入数字"))
y=x if x>=0 else -x
print(y)
第五章 循环:让计算机快速处理大量运算
5.1 while循环和嵌套
while语法:
while 条件:
条件满足时做的事情
条件满足时做的事情
例24:逐个输出0~100

!/usr/bin/python

i=0 #初始化while计数器
while i <=100: #设置循环条件
print(i) #打印i
i=i+1 #令i自增1
while循环嵌套语法:
while 条件1:
满足第1个事情时要做的事情
while 条件2:
满足第2个事情时要做的事情
注意!以下为重点。
例25:(输出九九乘法表):

!/usr/bin/python

i=1 #用i表示行数
while i <=9 :#共有9行
j=1 #用i表示列数
while j<=i: #当列数小于等于行数
print("j","","i","=",ji) #打印
j=j+1 #令列数自增1
i=i+1 #令行数自增15.2 for循环和嵌套
5.2 for循环和嵌套
for循环语句:
for 赋值目标 in 遍历对象
对赋值目标所做的操作
例26:逐行输出"hello world”

!/usr/bin/python

k="hello world" #赋值
for l in k #把k中的每一个字符赋值给l
print(l)
输出:
h
e
l
l
o
w
o
r
l
d
range()函数
在for循环中,通常使用range()函数做计数器
range函数语法:
range (start,stop,[step])
start:开始取数,类型为int
stop:结束取数,类型为int
step:可选,指取数的步值,类型为int
这么说你们可能不懂,来举几个实例:
例27-28:

!/usr/bin/python

for i in range(1,10):
print(i)
输出:
1
2
3
4
5
6
7
8
9

!/usr/bin/python

for i in range(1,10,2):
print(i)
输出:
1
3
5
7
9
注意!以下为重点。
例29:用for来实现九九乘法表

!/usr/bin/python

for i in range(1,10): #i表示行数
for j in range(1,i+1): #j表示列数
print("j","","i","=",ji,end=" ") #输出
print("\n") #换行
拓展(可以不学):在这里在给大家普及一下C语言的for语句:
For(赋值表达式,判断表达式,每做一次之后的动作)
例A:输出从1到100:

include

int main(){
int i;
for(i = 1;
i < 101;
i++){
printf("%d \n",i);
}
}第六章 字符串的秘密
6.1 字符串的创建
字符串可以按以下方法创建
"string" #用双引号包裹

'string' #用单引号包裹

"""
string
string
……
""" #用三引号包裹
6.2 字符串的索引
字符串:
"hello world"
索引
01234 56789
相信大家已经明白了
例30:
a =“I am zongzi”
for i in range(0,11):
print("第",i,"个索引表示的字符是",a[i])
程序执行如下:

6.3 字符串的常用操作方式
str为存放字符串的变量名
一.

字符串的大小写操作

str.capitalize() #大写字符串的第一个字母
str.swapcase() #全部大小写互换
str.lower() #小写字符串
str.upper() #大写字符串
例31:
a = "i am zongzi"
b = a.capitalize()
print(b)
b = a.swapcase()
print(b)
b = a.lower()
print(b)
b = a.upper()
print(b)
程序执行如下:

二.

字符串的一些判断

str.isalpha() #判断是否全都是字母
str.isdigit() #判断是否全都是数字
str.isspace() #判断是否全都是空字符
str.islower() #判断是否全都是小写
str.isupper() #判断是否全都是大写
例32:
a = "i am zongzi"
b = a.isalpha() #返回的是一个bool值,需要用一个变量存储。
print(b)
b = a.isdigit()
print(b)
b = a.isspace()
print(b)
b = a.islower()
print(b)
b = a.isupper()
print(b)
程序执行如下:
三.
str.center(width) #返回一个原字符串居中并用空格填充至width的字符串
str.find(substr[,start:[,end]]) #返回str中出现的第一个substr的索引号
str.rfind(substr[,start:[,end]]) #返回str中出现的最后一个substr的索引号
str.replace(old,new[,count]) #把str中的old替换为new,并执行count次
str.split([sep[,max]]) #以sep为分隔符,把str分割成一个列表并执行max次
str.strip([chars]) #把str中所有chars去掉
例32:
a="iamzongzi"
b = a.center(8)
print(b)
b = a.find("z")
print(b)
b = a.split("z")
print(b)

当然,有些想闲着没事搞一搞的会写出这样的代码:
st = input("请输入一个字符串:")
tr = input("请问你想测量哪个字符:")
re = st.split(tr)
result = len(re)
print(f"共有{result - 1}个{tr}字符!")
程序执行如下:
本章[]全部为可选参数
6.4字符串检索和修剪的基本方法
str.count("被检索的字符(串)[,检索起始位置[,检索终止位置]]")

统计该字符(串)在被检索的字符串中所出现的次数

str.find("被检索的字符(串)[,检索起始位置[,检索终止位置]]")

统计字符串中是否包含子字符(串),找到返回索引,找不到返回-1“

str.index("被检索的字符(串)[,检索起始位置[,检索终止位置]]")

统计字符串中是否包含子字符(串),找到返回索引,找不到报错

str.startwith("被检索的字符(串)[,检索起始位置[,检索终止位置]]")

查找字符串是否以指定字符串开头,是返回true,否返回false)

str.endwith("被检索的字符(串)[,检索起始位置[,检索终止位置]]")

查找字符串是否以指定字符串结尾,是返回true,否返回fals6.5 字符串的修剪

str.strip(chars)

移除字符串头尾的chars,默认是空格/换行符

str.lstrip(lchars)

移除字符串头的chars,默认是空格/换行符

str.strip(rchars)

移除字符串尾的chars,默认是空格/换行符

这里我讲的很明白,就不做演示了6.8 字符串的格式化

6.5字符串的格式化
6.8.1 过时的%占位符格式化
%后面可以跟一个字符,用来让你自己区分这个占位符是干什么的。
%占位符语法格式
print("你要说的内容%s你要说的内容%m"%(%s存放的变量名,%m(同上)))

其中%后面的命名不能随意随意,且与%()里的内容一一对应

如果是字符串一定要用%s,具体可以参考C语言。
例33:

name="刘宗恺"
age=6
password="wslzk"
print("%s今年%d岁,密码是%s,真的是%s"%(name,age,password,password))
程序执行如下:
但不推荐使用这种方法,你们看看就得了。
最后奉上一张占位符表:

6.5.2 即将过时的str.format()
即用{}用作占位符,但可以在{}内添加标号
举个例子你们就明白了
例34:
name="刘宗恺"
age=6
password="wslzk"
print("{n}今年{a}岁,密码是{p},真的是{p}".format(name,age,password))
程序执行如下:
这种方法应该已经行不通了,在QPython里会报KeyError
6.5.3 f—string格式化
f—string是python3.6中新加入的一种方法,起具有简单,实用性高,灵活性强的特点。
应用格式:
print(f"内容{}内容{}")
print(F"内容{}内容{}")
比较推荐{}内直接加变量
例35:
name="刘宗恺"
age=6
password="wslzk"
print(f”{name}今年{age}岁,密码是{password},真的是{password}")
程序执行如下:
第七章 高级数据类型
7.1 列表
7.1.1 列表及其基本属性
列表的特点:可新增,可删除,可重复,包含类型可以不同。
创建列表的方法:
1.直接给列表赋值
list1 = ["faq","和","laq"] #其中元素与元素之间用英文逗号分割。
2.创建空列表
list2 = []
列表的索引与字符串的索引类似,第一个元素的索引为0,第二个为1,以此类推。
例36:

usr/bin/python3

coding:utf-8

list1=["faq","和","laq"]
print(list1[1])
输出:

选学:列表嵌套
这里你们最好自己理解,我给一个例子:
例37:

usr/bin/python3

coding:utf-8

list3 = ["我","是"["faq","和","laq"]]
print(list[2][1])
输出:

7.1.2列表基本操作
拿好你的小本本,前方有大量语法出没!
注:list指你的列表的名字
list[列表索引] = 新的内容 #修改列表指定内容
list.append("内容")#向列表中添加内容
list.insert(索引,"内容") #向列表指定索引处添加内容
list.extend(另一个list) #合并两个列表
list.remove("内容") #删除列表中知道的内容(如果有多个,则删除第一个)
list.pop(索引) #删除指定索引出的内容,默认删除最后一个
list.clear() #清空列表 #以上方法都只在程序运行时内存里删,不在你写的程序里删
list.del() #清除列表
list.count("要统计的元素") #统计该元素在列表中出现的次数
len(list) #统计列表中有多少个元素
list.sort() #将列表正序排序(按照数字或字母顺序)
list.sort(reverse = true)#将列表逆序排序(按照数字或字母顺序)
list.reverse() #将列表直接倒过来排
例如你的老板让你把一个长长的字符串去掉所有的a,并且排序所有的不同的英文单词。
字符串:heaisapigasheepadoasomeathingsanotakillameapenadumpsahea
例36:
str1 = input("输入原本的字符串:")
list1 = str1.split("a")
list1.sort()
list1.pop(0)
set1 = set(list1)
print(set1)
程序执行如下:
把代码稍微改一改你就可以去编辞典了:
str1 = input("输入你要排序的单词,使用:来分割:")
list1 = str1.split(":")
list1.sort()
print(list1)程序执行如下:
模块测试
我们希望将一个字符串内只留下汉字,删除其它所有东西。
请综合运用之前的知识 给代码改错。
源代码如下:

我们一旦运行此代码,就会发现其局限性:

答案请发送至:[email protected]

7.2元组
7.2.1元组及其基本属性
元组的特点:元组(Tuple)与列表基本一样,只不过是不能修改。
创建元组的方法:
1.直接给元组赋值
tuple1=("faq","和","laq")#其中元素与元素之间用英文逗号分割。
2.创建空元组
tuple2=()
3.特别注意:如果元组中只有一个元素,则必须在它后面加",":
tuple3=(1,)
请不要这么写:
tuple3=(1)
元组的索引与字符串的索引类似,第一个元素的索引为0,第二个为1,以此类推。
例37:

usr/bin/python3

coding:utf-8

name=("faq","和","laq")
print(name[1])
输出:
元组的统计和列表是一样的,自己去看吧。
7.3 字典
7.3.1 字典及其基本属性
字典(dict)可以方便的将两个值"配对"。
如果你不明白,不要紧。看完下面的教程你就应该明白了。
字典的结构:
{"王":"王五","李":"李四","张":"张三"}
我们截取其中一对:
{"张":"张三"}
其中:前的内容叫key(键),:后的内容叫value(值)。我们可以方便的通过键找到其对应的值。
字典的创建:
dict1 = {}
Python并不是一门强类型语言,所以字典内允许各种数据,著名的强类型语言C#,在创建”花名册”字典时需要这么做:

  1. Dictionary = new Dictionary

字典对应值的寻找(例38):
dict1 = {"王":"王五","李":"李四","张":"张三"}
print(dict1["王"])
输出:

7.3.2 字典基本操作
警告:前方有大量语法出没

dict等就是你的字典变量名,以下方法请自己实践

dict.clear()#删除字典内所有元素,一个不留,清空字典
dict.fromkeys(seq[,value])#创建一新字典以seq中元素做字典的键,val为字典键的初始值
dict.get(key, default=None)#返回指定键(key)的值,如果值不在字典中返回default值。
dict.setdefault(key,default=None)#如果键不存在于字典中,将会添加键值设为default
dict.items()#以列表返回可遍历的键值元组数组,样式:(key,value)
dict.keys()#以列表返回一个字典所有的键(key),并不返回值(value)
dict.update(dict1)#把字典dict1的键值对更新到dict里
dict.values()#以列表返回字典中的所有值
dict.pop(key[,default])#删除指定的key及其所对的value值
例39:
dict1 = {"王":"王五","李":"李四","张":"张三"}
dict2 = {"王":"王二麻子"}
print(dict1.items())
print(dict1.keys())
dict1.update(dict2)
print(dict1.items())
dict1.pop("李")
print(dict1.items())
程序执行如下:

7.4 集合
集合的特性人人皆知,就是剔除不一样的元素,在这里就不再赘述。
例40(让列表中不包含同样的元素):
num = []
for i in range(1,11):
print(f"请输入10个数字,当前是第{i}个",end =":")
inp = int(input())
num.append(inp)
num2 = set(num)
print(f"不同的数字有{str(num2)}")

第八章 函数
8.1 函数是什么
从这一篇教程开始,你会明白Python没有你想象中的那么简单。
注意:Python的函数不同于数学函数。
数学函数:
定义:函数(function)的定义通常分为传统定义和近代定义,函数的两个定义本质是相同的,只是叙述概念的出发点不同,传统定义是从运动变化的观点出发,而近代定义是从集合、映射的观点出发。函数的近代定义是给定一个数集A,假设其中的元素为x,对A中的元素x施加对应法则f,记作f(x),得到另一数集B,假设B中的元素为y,则y与x之间的等量关系可以用y=f(x)表示,函数概念含有三个要素:定义域A、值域B和对应法则f。其中核心是对应法则f,它是函数关系的本质特征。
也即函数指一个量随着另一个量的变化而变化,或者说一个量中包含另一个量。
形式:
f(x) = kx
f(x) = kx + b #直线
f(x) = ax² + bx + c #抛物线
f(x) = ax³ + bx² + cx + d #回归式抛物线
...
计算机函数:
定义:函数是指一段可以直接被另一段程序或代码引用的程序或代码。也叫做子程序、(OOP中)方法。
一个较大的程序一般应分为若干个程序块,每一个模块用来实现一个特定的功能。所有的高级语言中都有子程序这个概念,用子程序实现模块的功能。在C语言中,子程序的作用是由一个主函数和若干个函数构成。由主函数调用其他函数,其他函数也可以互相调用。同一个函数可以被一个或多个函数调用任意多次。
形式:
int main(){

C

}

public static void main(String[] args){

Java

}

def main():
#Python
我们可以看出,Python中的函数定义是最简单的。
为什么要使用函数?百度百科中给出了如下结论:
在程序设计中,常将一些常用的功能模块编写成函数,放在函数库中供公共选用。要于利用函数,以减少重复编写程序段的工作量。
说句人话:函数有利于增强程序可读性,让程序更简洁。
8.2 定义函数的内容
在Python中,我们使用def()语句来定义函数,即:
def 函数名(*参数1,参数2...):
函数的内容

正常的程序
例41:输出五个hello world:
方法1:
print("hello world")
print("hello world")
print("hello world")
print("hello world")
print("hello world")

方法2:

for i in range(0,5):
print("hello world")

方法3:

def hw(count):
for i in range(0,count):
print("hello world")
hw(5)
我觉得第3种方法更可读,你呢?
8.3global和nonlocal关键字,内联和闭包函数
def f1():
print("this is f1!")
def f11():
print("this is f11!")
这时我们可以通过f1()调用,显示正常,但是我们调用f11时,却不会成功。因为Python无法在一级函数里找到f11()。
这时,我们称f11()是f1()的内联函数(Inline function)。
但如果我们的函数内有变量呢?我们可以使用nonlocal和global关键字。
它们的区别在哪里呢?我们来看一张图。

如果二级函数内有一个变量h,那么使用nonlocal h之后,我们可以在一级函数内使用h,使用global h之后,我们可以在主程序内使用h。
接着我们继续使用上面的例子,f1对f11内部作用。使用一个变量赋值调用的方法称为闭包(closure)
不懂也没有关系,我们以后会举例子使你明白。
8.4构造函数 解构函数
8.5 lambda表达式
Lambda表达式是Python中一类特殊的定义函数的形式,使用它可以定义一个匿名函数。与其它语言不同,Python的Lambda表达式的函数体只能有单独的一条语句,也就是返回值表达式语句。其语法如下:
lambda 原函数的参数 : 函数返回值表达式语句
例42:

定义一种变换,使传进去的参数+8,然后输出。

def形式

def b(x):
x = x + 1
print(x)

lambda表达式

b = lambda x:x + 8
其中,= 代表将lambda表达式的内容赋值给b,x代表调用时需要传入一个x参数,:后面的语句代表要对x执行的内容。
程序执行如下(lambda表达式版):

P

课后作业(升级挑战):
li=[{"age":20,"name":"def"},{"age":25,"name":"abc"},{"age":10,"name":"ghi"}]
li=sorted(li, key=lambda x:x["age"])
print(li)
作业要求:把它写成def的形式。

答案如下:
def comp(x):
return x["age"]
li=[{"age":20,"name":"def"},{"age":25,"name":"abc"},{"age":10,"name":"ghi"}]
li=sorted(li, key=comp)
print(li)
第九章 类 对象 面向对象
9.1 什么是类
类是一种用户定义的引用数据类型,也称类类型。每个类包含数据说明和一组操作数据或传递消息的函数。类的实例称为对象。
类,可以理解为一个箱子,里边封装了一大堆的函数、变量...当你有需要时可以随时调用它们。
9.2 定义和调用类
Python中定义一个类:

class a():
def b():
print("粽子和小恺")
...
接着我们来看一个极其沙雕的计算器:
例43:

Play section photoelectric/Toys World Science and Technology Department

class info:
def andder():
print("计算加法...")
def subber():
print("计算减法...")
def muller():
print("计算乘法...")
def divver():
print("计算除法...")
def init(args):
print("感谢使用我的计算器")
def del(
args):
print("离开...")
def error():
print("请不要乱输入!")

class do:
def andder(num1,num2):
print(str(int(num1) + int(num2)))
def sub(num1,num2):
print(str(int(num1) - int(num2)))
def mul(num1,num2):
print(str(int(num1) * int(num2)))
def div(num1,num2):
print(str(int(num1) / int(num2)))

while 1:
num1 = input("输入第一个数:")
num2 = input("输入第二个数:")
user = input("输入运算类型(加/减/乘/除)")

if user == "加":
    info.andder()
    do.andder(num1,num2)
elif user == "减":
    info.subber()
    do.sub(num1,num2)
elif user == "乘":
    info.muller()
    do.mul(num1,num2)
elif user == "除":
   info.divver()
   do.div(num1,num2)
else:
    info.error()
    break

程序执行如下:

运行很正常,接着我们来调戏它。
直接输入info(),调用info类。
输出:
感谢使用我的计算器
离开...
这样大家也好明白,init()方法直接发生于整个类被调用后,而del()方法直接发送于整个类调用结束之后。只要有指定的类调用方法(例如info.divver()),就不会触发init()方法和del()方法。同时也说明了直接调用类并不会触及到里面的方法。
继续调戏它,直接输入do()来调用一下这个类试试。
什么也没有发生,安然无事。
这也说明了不调用类里面需要参数的方法时,不需要传入此参数。
如何调用类里面的方法,刚才的程序里说的很明白。使用一个点号运算符(.)来调取类里面的方法。
调用格式如下:
类名.方法(*参数)
9.3 构造 解构
当一个类被直接调用是,会立即执行init()函数,当结束调用是,会立即执行del()方法,于是我们把init()称为构造函数,把del()称为解构函数。
构造函数和结构函数可以直接在类中定义。
例44:
class Test():
def init():
print("Test类被直接调用...")
def del():
print("Test结束调用...")
def others():
print("直接调用方法不会引发构造或解构..."
print("我们直接调用Test类:")
Test()
print("我们调用others方法:")
Test.others(0)
程序执行如下: *

9.4 面向对象编程概念(Object Oriented Programming,OOP)
OO方法(Object-Oriented Method,面向对象方法,面向对象的方法)是一种把面向对象的思想应用于软件开发过程中,指导开发活动的系统方法,简称OO (Object-Oriented)方法,是建立在“对象”概念基础上的方法学。对象是由数据和容许的操作组成的封装体,与客观实体有直接对应关系,一个对象类定义了具有相似性质的一组对象。而每继承性是对具有层次关系的类的属性和操作进行共享的一种方式。所谓面向对象就是基于对象概念,以对象为中心,以类和继承为构造机制,来认识、理解、刻画客观世界和设计、构建相应的软件系统。

OO方法用于系统开发有如下优越性:
(1) 强调从现实世界中客观存在的事物(对象)出发来认识问
题域和构造系统,这就使系统开发者大大减少了对问题域的理解难度,从而使系统能更确地反映问题域。
(2) 运用人类日常的思维方法和原则(体现于OO方法的抽
象、分类、继承、封装、消息通讯等基本原则)进行系统开发,有益于发挥人类的思维能力,并有效地控制了系 统复杂性。
(3) 对象的概念贯穿于开发过程的终,使各个开发阶段的系统
成分具良好的对应,从而显著地提高了系统的开发效率与质量,并大大降低系统维护的难度。
(4) 对象概念的一致性,使参与系统开发的各类人员在开发的各所段具有共同语言,有效地改善了人员之间的 交流和协作。
(5) 对象的相对稳定性和对易变因素隔离,增强了系统的应变能力。
(6) 对象类之间的继承关系和对象的相对独立性,对软件复用提供了强有力的支持。

9.5 面向对象(Object Oriented,OO)

9.5.1 封装

类的封装性即不能让外面的类随意修改一个类的成员变量;保证了类的安全。
Python封装类(例45):

class Animal:
eye = 2
leg = 4 #共有的
def init(self,name,food):
print('正在实例化')
self.name = name
self.food = food

def get_name(self):
    print(self.name)

def get_food(self):
    print(self.food)

这样就很好的保护了类的安全。

9.5.2继承

 用法:
在定义类时,可以从已有的类继承,
被继承的类称为基类(父类),新定义的类称为派生类(子类)。

 在类中找不到调用的属性时就搜索基类,
 如果基类是从别的类派生而来,这个规则会递归的应用上去。
 反过来不行。

 如果派生类中的属性与基类属性重名,那么派生类的属性会覆盖掉基类的属性。
 包括初始化函数。

派生类在初始化函数中需要继承和修改初始化过程,
 使用类名+__init__(arg)来实现继承和私有特性,也可以使用super()函数。

issubclass(类名1,类名2)
判断类1是否继承了类2

 作用:
面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。
继承完全可以理解成类之间的类型和子类型关系。

子类在重写父类方法之后,如果要继承父类方法中的功能,要先调用父类的方法  class.fun(self)

接着看如下一段代码(例46):
class Animal:
eye = 2
leg = 4 #共有的
def init(self,name,food):
print('正在实例化')
self.name = name
self.food = food

def get_name(self):
    print(self.name)

def get_food(self):
    print(self.food)

继承

面向对象的编程带来的主要好处之一是代码的重用

class People(Animal):
leg = 2
def init(self,name,food,sex):
self.name = name
self.food = food
self.sex = sex

def get_sex(self):
    print(self.sex)

def speak(self):
    print('asdsdgfsagg')

def eat(self):
    print('果子')

我们试图调用Animal类的get_name()方法。
Animal.get_name()
接着编译器毫不犹豫的报错了:
意思很明显,少了一个叫做”self”的参数。
接着你大概会往里面继续传各种参数:
Animal.get_name(0)
Animal.get_name("horse")
然后编译器继续报错,你会开始觉得学到了假的Python。
别害怕!这正是面向对象的精髓所在,我们需要先创建一个符合init()的对象。
观察init:
def init(self,name,food):
不要管self是什么,去掉self后的构造函数需要两个参数:name和food。
于是我们创建一个符合条件的对象:
Xm = Animal('小明','树叶')
然后调用他的方法:
Xm.get_name()
编译器正常输出:

这时你可能会问,这个小明是什么数据类型?其实小明现在就是Animal类型。
我们可以看到,这时的People类并没有get_name()等方法,但它继承于Animal,所以我们依然可以使用其get_name()等方法,这便称作”类的继承”。

9.5.3 多态
有时我们需要子类重写父类方法,这便称作”多态”。

以上 封装 继承 多态就是面向对象的三大特征。

9.6 函数装饰器
这个东西说简单很简单,但我老是讲不明白。就借用了一些菜鸟教程的文章。
装饰器(Decorators)是 Python 的一个重要部分。简单地说:他们是修改其他函数的功能的函数。他们有助于让我们的代码更简短,也更Pythonic(Python范儿)。大多数初学者不知道在哪儿使用它们,所以我将要分享下,哪些区域里装饰器可以让你的代码更简洁。 首先,让我们讨论下如何写你自己的装饰器。

这可能是最难掌握的概念之一。我们会每次只讨论一个步骤,这样你能完全理解它。

一切皆对象
首先我们来理解下 Python 中的函数:

def hi(name="toysworld"):
return "hi " + name

print(hi())

output: 'hi toysworld'

我们甚至可以将一个函数赋值给一个变量,比如

greet = hi

我们这里没有在使用小括号,因为我们并不是在调用hi函数

而是在将它放在greet变量里头。我们尝试运行下这个

print(greet())

output: 'hi toysworld'

如果我们删掉旧的hi函数,看看会发生什么!

del hi
print(hi())

outputs: NameError

print(greet())

outputs: 'hi toysworld'

在函数中定义函数
刚才那些就是函数的基本知识了。我们来让你的知识更进一步。在 Python 中我们可以在一个函数中定义另一个函数:

def hi(name="toysworld"):
print("now you are inside the hi() function")

def greet():
    return "now you are in the greet() function"

def welcome():
    return "now you are in the welcome() function"

print(greet())
print(welcome())
print("now you are back in the hi() function")

hi()

output:now you are inside the hi() function

now you are in the greet() function

now you are in the welcome() function

now you are back in the hi() function

上面展示了无论何时你调用hi(), greet()和welcome()将会同时被调用。

然后greet()和welcome()函数在hi()函数之外是不能访问的,比如:

greet()

outputs: NameError: name 'greet' is not defined

那现在我们知道了可以在函数中定义另外的函数。也就是说:我们可以创建嵌套的函数。现在你需要再多学一点,就是函数也能返回函数。

从函数中返回函数
其实并不需要在一个函数里去执行另一个函数,我们也可以将其作为输出返回出来:

def hi(name="toysworld"):
def greet():
return "now you are in the greet() function"

def welcome():
    return "now you are in the welcome() function"

if name == "toysworld":
    return greet
else:
    return welcome

a = hi()
print(a)

outputs:

上面清晰地展示了a现在指向到hi()函数中的greet()函数

现在试试这个

print(a())

outputs: now you are in the greet() function

再次看看这个代码。在 if/else 语句中我们返回 greet 和 welcome,而不是 greet() 和 welcome()。为什么那样?这是因为当你把一对小括号放在后面,这个函数就会执行;然而如果你不放括号在它后面,那它可以被到处传递,并且可以赋值给别的变量而不去执行它。 你明白了吗?让我再稍微多解释点细节。

当我们写下 a = hi(),hi() 会被执行,而由于 name 参数默认是 toysworld,所以函数 greet 被返回了。如果我们把语句改为 a = hi(name = "ali"),那么 welcome 函数将被返回。我们还可以打印出 hi()(),这会输出 now you are in the greet() function。

将函数作为参数传给另一个函数
def hi():
return "hi toysworld!"

def doSomethingBeforeHi(func):
print("I am doing some boring work before executing hi()")
print(func())

doSomethingBeforeHi(hi)

outputs:I am doing some boring work before executing hi()

hi toysworld!

现在你已经具备所有必需知识,来进一步学习装饰器真正是什么了。装饰器让你在一个函数的前后去执行代码。

你的第一个装饰器
在上一个例子里,其实我们已经创建了一个装饰器!现在我们修改下上一个装饰器,并编写一个稍微更有用点的程序:

def a_new_decorator(a_func):

def wrapTheFunction():
    print("I am doing some boring work before executing a_func()")

    a_func()

    print("I am doing some boring work after executing a_func()")

return wrapTheFunction

def a_function_requiring_decoration():
print("I am the function which needs some decoration to remove my foul smell")

a_function_requiring_decoration()

outputs: "I am the function which needs some decoration to remove my foul smell"

a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)

now a_function_requiring_decoration is wrapped by wrapTheFunction()

a_function_requiring_decoration()

outputs:I am doing some boring work before executing a_func()

I am the function which needs some decoration to remove my foul smell

I am doing some boring work after executing a_func()

你看明白了吗?我们刚刚应用了之前学习到的原理。这正是 python 中装饰器做的事情!它们封装一个函数,并且用这样或者那样的方式来修改它的行为。现在你也许疑惑,我们在代码里并没有使用 @ 符号?那只是一个简短的方式来生成一个被装饰的函数。这里是我们如何使用 @ 来运行之前的代码:

@a_new_decorator
def a_function_requiring_decoration():
"""Hey you! Decorate me!"""
print("I am the function which needs some decoration to "
"remove my foul smell")

a_function_requiring_decoration()

outputs: I am doing some boring work before executing a_func()

I am the function which needs some decoration to remove my foul smell

I am doing some boring work after executing a_func()

the @a_new_decorator is just a short way of saying:

a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)
希望你现在对 Python 装饰器的工作原理有一个基本的理解。如果我们运行如下代码会存在一个问题:

print(a_function_requiring_decoration.name)

Output: wrapTheFunction

这并不是我们想要的!Ouput输出应该是"a_function_requiring_decoration"。这里的函数被warpTheFunction替代了。它重写了我们函数的名字和注释文档(docstring)。幸运的是Python提供给我们一个简单的函数来解决这个问题,那就是functools.wraps。我们修改上一个例子来使用functools.wraps:

from functools import wraps

def a_new_decorator(a_func):
@wraps(a_func)
def wrapTheFunction():
print("I am doing some boring work before executing a_func()")
a_func()
print("I am doing some boring work after executing a_func()")
return wrapTheFunction

@a_new_decorator
def a_function_requiring_decoration():
"""Hey yo! Decorate me!"""
print("I am the function which needs some decoration to "
"remove my foul smell")

print(a_function_requiring_decoration.name)

Output: a_function_requiring_decoration

现在好多了。我们接下来学习装饰器的一些常用场景。

蓝本规范:

from functools import wraps
def decorator_name(f):
@wraps(f)
def decorated(*args, *kwargs):
if not can_run:
return "Function will not run"
return f(
args, **kwargs)
return decorated

@decorator_name
def func():
return("Function is running")

can_run = True
print(func())

Output: Function is running

can_run = False
print(func())

Output: Function will not run

注意:@wraps接受一个函数来进行装饰,并加入了复制函数名称、注释文档、参数列表等等的功能。这可以让我们在装饰器里面访问在装饰之前的函数的属性。

带参数的装饰器
来想想这个问题,难道@wraps不也是个装饰器吗?但是,它接收一个参数,就像任何普通的函数能做的那样。那么,为什么我们不也那样做呢? 这是因为,当你使用@my_decorator语法时,你是在应用一个以单个函数作为参数的一个包裹函数。记住,Python里每个东西都是一个对象,而且这包括函数!记住了这些,我们可以编写一下能返回一个包裹函数的函数。

在函数中嵌入装饰器
我们回到日志的例子,并创建一个包裹函数,能让我们指定一个用于输出的日志文件。

from functools import wraps

def logit(logfile='out.log'):
def logging_decorator(func):
@wraps(func)
def wrapped_function(*args, *kwargs):
log_string = func.name + " was called"
print(log_string)
# 打开logfile,并写入内容
with open(logfile, 'a') as opened_file:
# 现在将日志打到指定的logfile
opened_file.write(log_string + '\n')
return func(
args, **kwargs)
return wrapped_function
return logging_decorator

@logit()
def myfunc1():
pass

myfunc1()

Output: myfunc1 was called

现在一个叫做 out.log 的文件出现了,里面的内容就是上面的字符串

@logit(logfile='func2.log')
def myfunc2():
pass

myfunc2()

Output: myfunc2 was called

现在一个叫做 func2.log 的文件出现了,里面的内容就是上面的字符串

装饰器类
现在我们有了能用于正式环境的logit装饰器,但当我们的应用的某些部分还比较脆弱时,异常也许是需要更紧急关注的事情。比方说有时你只想打日志到一个文件。而有时你想把引起你注意的问题发送到一个email,同时也保留日志,留个记录。这是一个使用继承的场景,但目前为止我们只看到过用来构建装饰器的函数。

幸运的是,类也可以用来构建装饰器。那我们现在以一个类而不是一个函数的方式,来重新构建logit。

from functools import wraps

class logit(object):
def init(self, logfile='out.log'):
self.logfile = logfile

def __call__(self, func):
    @wraps(func)
    def wrapped_function(*args, **kwargs):
        log_string = func.__name__ + " was called"
        print(log_string)
        # 打开logfile并写入
        with open(self.logfile, 'a') as opened_file:
            # 现在将日志打到指定的文件
            opened_file.write(log_string + '\n')
        # 现在,发送一个通知
        self.notify()
        return func(*args, **kwargs)
    return wrapped_function

def notify(self):
    # logit只打日志,不做别的
    pass

这个实现有一个附加优势,在于比嵌套函数的方式更加整洁,而且包裹一个函数还是使用跟以前一样的语法:

@logit()
def myfunc1():
pass
现在,我们给 logit 创建子类,来添加 email 的功能(虽然 email 这个话题不会在这里展开)。

class email_logit(logit):
'''
一个logit的实现版本,可以在函数调用时发送email给管理员
'''
def init(self, email='[email protected]', *args, *kwargs):
self.email = email
super(email_logit, self).init(
args, **kwargs)

def notify(self):
    # 发送一封email到self.email
    # 这里就不做实现了
    pass

从现在起,@email_logit 将会和 @logit 产生同样的效果,但是在打日志的基础上,还会多发送一封邮件给管理员。

原文地址:https://eastlakeside.gitbooks.io/interpy-zh/content/decorators/

第十章 底层逻辑

10.1 魔法方法
魔法方法 如何使用
len(self) 定义当被 len() 调用时的行为
repr(self) 定义当被 repr() 调用时的行为
str(self) 定义当被 str() 调用时的行为
bytes(self) 定义当被 bytes() 调用时的行为
hash(self) 定义当被 hash() 调用时的行为
bool(self) 定义当被 bool() 调用时的行为,应该返回 True 或 False
format(self, format_spece) 定义当被 format() 调用时的行为
getattr(self, name) 定义当用户试图获取一个不存在的属性时的行为
getattribute(self, name) 定义当该类的属性被访问时的行为
setattr(self, name, value) 定义当一个属性被设置时的行为
delattr(self, name) 定义当一个属性被删除时的行为
dir(self) 定义当 dir() 被调用时的行为
get(self, instance, owner) 定义当描述符的值被取得时的行为
set(self, instance, value) 定义当描述符的值被改变时的行为
delete(self, instance) 定义当描述符的值被删除时的行为
类型 比较操作符
lt(self, other) 定义小于号的行为:x < y 调用 x.lt(y)
le(self, other) 定义小于等于号的行为:x <= y 调用 x.le(y)
eq(self, other) 定义等于号的行为:x == y 调用 x.eq(y)
ne(self, other) 定义不等号的行为:x != y 调用 x.ne(y)
gt(self, other) 定义大于号的行为:x > y 调用 x.gt(y)
ge(self, other) 定义大于等于号的行为:x >= y 调用 x.ge(y)
类型 算数运算符
add(self, other) 定义加法的行为:+
sub(self, other) 定义减法的行为:-
mul(self, other) 定义乘法的行为:*
truediv(self, other) 定义真除法的行为:/
floordiv(self, other) 定义整数除法的行为://
mod(self, other) 定义取模算法的行为:%
divmod(self, other) 定义当被 divmod() 调用时的行为
pow(self, other[, model]) 定义当被 power() 调用或 ** 运算时的行为
lshift(self, other) 定义按位左移位的行为:<<
rshift(self, other) 定义按位右移位的行为:>>
and(self, other) 定义按位与操作的行为:&
xor(self, other) 定义按位异或操作的行为:^
or(self, other) 定义按位或操作的行为:
类型 反运算
radd(self, other) (与add相同,当左操作数不支持相应的操作时被调用)
rsub(self, other) (与sub相同,当左操作数不支持相应的操作时被调用)
rmul(self, other) (与mul相同,当左操作数不支持相应的操作时被调用)
rtruediv(self, other) (与truediv相同,当左操作数不支持相应的操作时被调用)
rfloordiv(self, other) (与floordiv相同,当左操作数不支持相应的操作时被调用)
rmod(self, other) (与mod相同,当左操作数不支持相应的操作时被调用)
rdivmod(self, other) (与divmod相同,当左操作数不支持相应的操作时被调用)
rpow(self, other) (与pow相同,当左操作数不支持相应的操作时被调用)
rlshift(self, other) (与lshift相同,当左操作数不支持相应的操作时被调用)
rrshift(self, other) (与rshift相同,当左操作数不支持相应的操作时被调用)
rand(self, other) (与and相同,当左操作数不支持相应的操作时被调用)
rxor(self, other) (与xor相同,当左操作数不支持相应的操作时被调用)
ror(self, other) (与or相同,当左操作数不支持相应的操作时被调用)
其它 反操作就是左边数不能操作时用的,例如l = 1313 不能说1313 = l
类型 增量赋值运算
iadd(self, other) 定义赋值加法的行为:+=
isub(self, other) 定义赋值减法的行为:-=
imul(self, other) 定义赋值乘法的行为:=
itruediv(self, other) 定义赋值真除法的行为:/=
ifloordiv(self, other) 定义赋值整数除法的行为://=
imod(self, other) 定义赋值取模算法的行为:%=
ipow(self, other[, modulo]) 定义赋值幂运算的行为:
*=
ilshift(self, other) 定义赋值按位左移位的行为:<<=
irshift(self, other) 定义赋值按位右移位的行为:>>=
iand(self, other) 定义赋值按位与操作的行为:&=
ixor(self, other) 定义赋值按位异或操作的行为:^=
ior(self, other) 定义赋值按位或操作的行为: =
类型 一元操作符
pos(self) 定义正号的行为:+x
neg(self) 定义负号的行为:-x
abs(self) 定义当被 abs() 调用时的行为
invert(self) 定义按位求反的行为:~x
类型 转换
complex(self) 定义当被 complex() 调用时的行为(需要返回恰当的值)
int(self) 定义当被 int() 调用时的行为(需要返回恰当的值)
float(self) 定义当被 float() 调用时的行为(需要返回恰当的值)
round(self[, n]) 定义当被 round() 调用时的行为(需要返回恰当的值)
类型 容器
len(self) 定义当被 len() 调用时的行为(返回容器中元素的个数)
getitem(self, key) 定义获取容器中指定元素的行为,相当于 self[key]
setitem(self, key, value) 定义设置容器中指定元素的行为,相当于 self[key] = value
delitem(self, key) 定义删除容器中指定元素的行为,相当于 del self[key]
iter(self) 定义当迭代容器中的元素的行为
reversed(self) 定义当被 reversed() 调用时的行为
contains(self, item) 定义当使用成员测试运算符(in 或 not in)时的行为

10.2重写底层逻辑*

我们来举个例子,编程语言中的索引总是从0开始,让人很难受,我们该怎么办呢?
我们可以通过函数的方法直接重新定义底层逻辑:
def 魔法方法(参数):
调用时发生的事情

查表,得:
getitem(self, key) 定义获取容器中指定元素的行为,相当于 self[key]
setitem(self, key, value) 定义设置容器中指定元素的行为,相当于 self[key] = value
delitem(self, key) 定义删除容器中指定元素的行为,相当于 del self[key]
于是可以如此写程序(例47):
def getitem(self,key):
return self[key + 1]
def setitem(self, key, value):
self[key + 1] = value
def delitem(self, key):
del self[key + 1]
第十一章 错误处理
11.1 为什么要进行错误处理
说到错误处理,大家可能都会觉得只要出错编译器就会报错,那意义在哪里呢?
让我们来看例18。
例18(一个简单的加法计算器):
x1=int(input(“请输入第一个数:”))
x2=int(input(“请输入第二个数:”))
y=x1+x2
print(“结果是”,y)
如果我输入1,再输入5,就会正常的输入6。
但是当我输入一个e…
编译器毫不犹豫的抛出了ValueError,如果用户看到了这段信息,一定会以为我们的程序有bug。
所以我们有必要进行错误处理。
11.2 简单的错误处理语句
我们使用try(尝试)语句进行错误处理,语法如下:
如果不填错误类型,那么会抓取全部错误,如果写了as 变量,那么这个变量就会存储错误原因。
例48:
程序执行如下:

11.3 错误处理全语法
本小节所讲的语法在文件操作时最有用,所以在此不做探究。
Try语句全语法如下:

11.4 assert断言语句
Assert是个很暴躁的家伙,一旦后面的语句不符合他的断言标准,他就会立即抛出一个错误,终止程序运行。
Assert语句语法如下:
Assert语句在搭配try语句时最有用。
例49:

程序执行如下:
特别注意:断言语句在调试中有效,如果想使他失去作用,在执行时添加一个-O参数。

第十二章 文件操作

12.1 File对象
我们有两种方式创建文件对象,一般使用直接赋值法。
例如:
f1 = open('d:\测试文件.txt', mode='r', encoding='utf-8')
open函数有三个参数,分别是:路径[模式][,编码]。
其中路径就是文件的位置,右击文件<>属性就能找到。但是Python不接受一个直接的路径,Python会认为那是一个转义序列。
对于文件路径”C:\users\administrator\desktop\study”我们有三种写法:
 ” C:\users\administrator\desktop\study”;
 R” C:\users\administrator\desktop\study” ;
 “C:/users/administrator/desktop/study”.
模式有:
 r 只读模式【默认模式,文件必须存在,不存在则抛出异常】
 w 只写模式【不可读;不存在则创建;存在则清空内容在写入】
 a 只追加写模式【不可读;不存在则创建;存在则只追加内容】
 b 字节二进制模式 【读取无法直接读取的文档】
 r+b 读写【可读,可写】
 w+b 写读【可写,可读】
 a+b 写读【可追加写,可读】
编码通常用utf-8,以下是几种常见的编码格式,有兴趣
可以扫描右侧二维码自行查阅。

ASCII 码
学过计算机的人都知道 ASCII 码,总共有 128 个,用一个字节的低 7 位表示,0~31 是控制字符如换行回车删除等;32~126 是打印字符,可以通过键盘输入并且能够显示出来。
ISO-8859-1
128 个字符显然是不够用的,于是 ISO 组织在 ASCII 码基础上又制定了一些列标准用来扩展 ASCII 编码,它们是 ISO-8859-1~ISO-8859-15,其中 ISO-8859-1 涵盖了大多数西欧语言字符,所有应用的最广泛。ISO-8859-1 仍然是单字节编码,它总共能表示 256 个字符。
GB2312
它的全称是《信息交换用汉字编码字符集 基本集》,它是双字节编码,总的编码范围是 A1-F7,其中从 A1-A9 是符号区,总共包含 682 个符号,从 B0-F7 是汉字区,包含 6763 个汉字。
GBK
全称叫《汉字内码扩展规范》,是国家技术监督局为 windows95 所制定的新的汉字内码规范,它的出现是为了扩展 GB2312,加入更多的汉字,它的编码范围是 8140~FEFE(去掉 XX7F)总共有 23940 个码位,它能表示 21003 个汉字,它的编码是和 GB2312 兼容的,也就是说用 GB2312 编码的汉字可以用 GBK 来解码,并且不会有乱码。
GB18030
全称是《信息交换用汉字编码字符集》,是我国的强制标准,它可能是单字节、双字节或者四字节编码,它的编码与 GB2312 编码兼容,这个虽然是国家标准,但是实际应用系统中使用的并不广泛。
UTF-16
说到 UTF 必须要提到 Unicode(Universal Code 统一码),ISO 试图想创建一个全新的超语言字典,世界上所有的语言都可以通过这本字典来相互翻译。可想而知这个字典是多么的复杂,关于 Unicode 的详细规范可以参考相应文档。Unicode 是 Java 和 XML 的基础,下面详细介绍 Unicode 在计算机中的存储形式。
UTF-16 具体定义了 Unicode 字符在计算机中存取方法。UTF-16 用两个字节来表示 Unicode 转化格式,这个是定长的表示方法,不论什么字符都可以用两个字节表示,两个字节是 16 个 bit,所以叫 UTF-16。UTF-16 表示字符非常方便,每两个字节表示一个字符,这个在字符串操作时就大大简化了操作。
UTF-8
UTF-16 统一采用两个字节表示一个字符,虽然在表示上非常简单方便,但是也有其缺点,有很大一部分字符用一个字节就 可以表示的现在要两个字节表示,存储空间放大了一倍,在现在的网络带宽还非常有限的今天,这样会增大网络传输的流量,而且也没必要。

UTF-8 有以下编码规则:
如果一个字节,最高位(第 8 位)为 0,表示这是一个 ASCII 字符(00 - 7F)。可见,所有 ASCII 编码已经是 UTF-8 了。
以下为ASCII编码表:

12.2 读写文件
在创建好文件对象后,我们可以直接调用文件对象内的方法。(使用点号)
f1 = open('d:\测试文件.txt', mode='r', encoding='utf-8')
f1.read() 可以读取文件。
f1.write(object)可以写入文件。
在读取和写入之后,一定要调用close()方法关闭文件 否则会产生文件占用的情况。
With f open(): 语句是第二种打开文件的方法,会自动关闭文件。
在出现错误后,使用try捕获,然后要在finally里关闭文件。
第十三章 包和模块
13.1 为什么有模块
模块(Module)用于方便的存储代码。同时Python可以方便的使用模块里的各种方法。
Python中最大的模块库是pypi,里面包含了不计其数的模块。
使用时间读者可以扫描右侧二维码方便的访问。

13.2 导入模块
我们有三种方法用来导入模块,分别是:
不同应用方法如下:
13.3 包
(菜鸟教程)包是一个分层次的文件目录结构,它定义了一个由模块及子包,和子包下的子包等组成的 Python 的应用环境。
简单来说,包就是文件夹,但该文件夹下必须存在 init.py 文件, 该文件的内容可以为空。init.py 用于标识当前文件夹是一个包。
考虑一个在 package_runoob 目录下的 runoob1.py、runoob2.py、init.py 文件,test.py 为测试调用包的代码,目录结构如下:
test.py
package_runoob
|-- init.py
|-- runoob1.py
|-- runoob2.py
源代码如下:
package_runoob/runoob1.py

!/usr/bin/python

-- coding: UTF-8 --

def runoob1():
print "I'm in runoob1"
package_runoob/runoob2.py

!/usr/bin/python

-- coding: UTF-8 --

def runoob2():
print "I'm in runoob2"
现在,在 package_runoob 目录下创建 init.py:
package_runoob/init.py

!/usr/bin/python

-- coding: UTF-8 --

if name == 'main':
print '作为主程序运行'
else:
print 'package_runoob 初始化'
然后我们在 package_runoob 同级目录下创建 test.py 来调用 package_runoob 包
test.py

!/usr/bin/python

-- coding: UTF-8 --

导入 Phone 包

from package_runoob.runoob1 import runoob1
from package_runoob.runoob2 import runoob2
runoob1() runoob2()
以上实例输出结果:
package_runoob 初始化
I'm in runoob1
I'm in runoob2
如上,为了举例,我们只在每个文件里放置了一个函数,但其实你可以放置许多函数。你也可以在这些文件里定义Python的类,然后为这些类建一个包。
第十四章 反射
14.1 反射
反射严谨解释:通过字符串的形式操作对象或模块中的成员。
反射通俗解释:反射就是从一个东西里取出属于他的成员
我们用成员调用来对比解释一下更清楚
正常调用:程序员自己知道什么时候调用哪个属性或方法。比如:对象.属性、对象.方法()。
反射调用:由用户来决定(输入或点击)什么时候调用哪个属性或方法。比如:g = getattr(对象, '属性或方法名')
操作成员包括判断、调用、设置、删除。

14.2元类方法

成员判断:hasattr(obj, 'age') 对象obj中存在age成员返回True,不存在返回False
成员调用:getattr(obj, 'age') 对象obj中取出age成员,age如果是方法则加小括号调用
成员设置:setattr(obj, 'age', 10) 对象obj中设置age成员属性为10
成员删除:delattr(obj, 'age') 对象obj中删除age成员
反射调用比正常调用要麻烦些,但是为什么要用反射调用呢?
原因:用户输入或点击的链接一般都是字符串形式(不是字符串也可以转换成字符串)

第十五章 两种设计模式(体验)

15.1简介
设计模式向来就是一个使人头皮发麻的东西。这一部分涉及到非常多的内容,但是我不会讲的太细。于是我们在网络上寻找了文字教程。如果不会可以读详细的文章。

15.2 单例模式
初学者喜欢用全局变量,因为这比函数的参数传来传去更容易让人理解。确实在很多场景下用全局变量很方便。不过如果代码规模增大,并且有多个文件的时候,全局变量就会变得比较混乱。你可能不知道在哪个文件中定义了相同类型甚至重名的全局变量,也不知道这个变量在程序的某个地方被做了怎样的操作。
因此对于这种情况,有种更好的实现方式:
单例(Singleton)

单例是一种设计模式,应用该模式的类只会生成一个实例。
单例模式保证了在程序的不同位置都可以且仅可以取到同一个对象实例:如果实例不存在,会创建一个实例;如果已存在就会返回这个实例。因为单例是一个类,所以你也可以为其提供相应的操作方法,以便于对这个实例进行管理。
15.3 简单工厂
简单工厂模式是类的创建模式,又叫做静态工厂方法模式。就是由一个工厂类根据传入的参量决定创建出哪一种产品类的实例。
从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
 工厂角色
简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。
 简单工厂模式:通过接口创建对象,且不会暴露对象创建逻辑

你可能感兴趣的:(超级秘籍 | 纯文本--Python从入门到精通)