使用python已经有一段时间了,先是python2,后是python3,有时用着用着也就分不清用的是python2的语法还是python3的语法了,在此做个总结,重点关注python2与python3的差别及一些要点,容易生疏的用法。
Python3的数据类型
不可变数据:Number(数字)、String(字符串)、Tuple(元组);
可变数据(:List(列表)、Dictionary(字典)、Set(集合)。
Python3中bool也是int类型,1和True相等,0和False相等;
repr(x) 将对象 x 转换为表达式字符串
T={"name":"Google"}
repr(T)
输出为 “{‘name’:‘Google’}”
eval(str) 用来计算在字符串中的有效Python表达式,并返回一个对象
x = 7
eval( '3 * x' )
输出为 21
Python3的推导式
从一个数据序列构建一个新的数据序列, 各种数据结构也可以混合使用
列表
a=[1,2,3,4]
b=[i*3 for i in a]
c=[i*4 for i in a if i > 2]
两种情况分别是没有加判断条件和加了判断条件,由原列表构建了一个新的列表;得出b为[3,6,9,12] , c 为[12,16]
字典
a={"A":1,"B":2}
b={key:a[key]+3 for key in a}
c={key:a[key]+3 for key in a if a[key] > 1}
b为{‘A’: 4, ‘B’: 5}
c为{‘B’: 5}
集合和元组
集合推导式和元组推导式的格式也比较类似;
字符串格式化 f-string
用法概述: f放在字符串前面,变量放在大括号中
a={"A":1,"B":2}
f"A is {a['A']}" #python3.6引入
得出的结果是 ‘A is 1’
x=1
print(f'{x+1=}')
得出的结果是 x+1=2
unicode 字符串
python2中普通字符传用ASCII存储,unicode用16位unicode字符串存储,使用时要在前面加u;
python3中所有字符串都为unicode;
encode与decode方法
python3相比python2在编码上能节省不少功夫;
s="12121"
s.encode("utf-8", errors="strict")
b.decode(encoding="utf-8", errors="strict")
除法
8/3 = 2.6666666666666665
8//3 = 2
函数
不定长参数
传入参数为元组, 用 *
def functionname([formal_args,] *var_args_tuple ):
function_suite
return [expression]
def printinfo( arg1, **vardict ):
print (arg1)
print (vardict)
printinfo( 70, a=60, b=50 )
传入参数为字典, 用 **
def printinfo( arg1, *vartuple ):
print (arg1)
print (vartuple)
printinfo( 70, 60, 50 )
lamda函数(lamda表达式)
lamda函数也叫做lamda表达式, 传入参数返回表达式结果
lambda [arg1 [,arg2,.....argn]]:expression
x = lambda a : a + 10
print(x(5))
sum = lambda arg1, arg2: arg1 + arg
print(sum(3,5))
输出为 :
15
8
__name__属性
当一个模块被引入时,其主程序会被执行,可以通过__name__判断是不是main来 避免; 一个模块指挥被引入一次;
if __name__ == '__main__':
print('程序自身在运行')
else:
print('我来自另一模块')
dir() 函数
dir() 可以找到模块内定义的所有名称
包
包是目录中包含一个__init__.py ,当我们使用from A import * 时会引用所有文件,这种情况我们可以在__init__.py中指定;
__all__=["echo", "surround", "reverse"]
这样我们就可以在
from A import __all__
时只引入特定的模块
导入包时建议使用绝对路径
异常处理
try 正常执行代码
except 异常时执行
else 没有异常执行
finally 有无异常均执行
finally
通常用finally来执行清理工作,
finally不会执行的情况包括:
- 没有进try块
- 调用了exit退出
常见疑问:
- except中有return还会不会执行到finally?
会
注意事项:
- 在finally中不要使用return。
会出现以下问题:- 在finally中使用 return 同时在try或except中有return时,finally中的return会替换掉try或expect中的return值;
- 如果在except块中有异常时,因为finally中的return,异常也会不会抛出;
def func1():
try:
print("in try")
raise ValueErrror("error")
except:
print("in expect")
return 1
finally:
print("finally")
return 2
代码的输出为:
in try
in expect
finally
2
浅拷贝和深拷贝
- 浅拷贝和深拷贝分别是什么?
浅拷贝只拷贝基本元素,像复杂的数据类型,字典,列表,元组等不会拷贝;
深拷贝则是所有的数据都会拷贝一份,不会影响原来的数据;
a={'a':[1,2,3]}
b = a #赋值,传对象的引用
c = a.copy() #浅拷贝
d = copy.deepcopy(a) #深拷贝
- 什么时候使用浅拷贝?
原始的复杂数据结构不会改变,希望节省内存 - 什么时候使用深拷贝?
原始数据会新数据可能会发生改变
装饰器
装饰器的目的是实现无侵入式的增加功能,可以用于日志记录,性能统计等场景;可以考虑下我们是否可以通过此功能实现一些debug功能;
import time
def logtime(func):
def wrapper(*args, **kwargs):
start = time.time()
func(*args, **kwargs)
end = time.time()
print("used time %d s" %int(end - start))
return wrapper
@logtime
def func():
time.sleep(5)