首页 > Python基础教程 >
-
python基础总结(3)
exec():与eval()几乎一样,但是它是处理代码流的。工作时最好不用,容易中病毒。
msg = """
for i in range(5):
print(i)"""
exec(msg) #0,1,2,3,4
hash:获取一个对象(可哈希对象:int,str,bool,tuple)的哈希值。哈希值:加密算法之间需要哈希值,与哈希算法有关。
print(hash('12'))
help():打印/获取一个对象的使用方法。
print(help(str))
print(help(str.upper))
callable():判断一个对象是否可调用,真为True,假为False。
l1 = [1,2]
def func():
pass
print(callable(l1)) #False
print(callable(func)) #True
int():将字符串类型转换为int类型;取整(舍尾法)
float():将int和str转换为float。
list():将一个可迭代对象转换成列表
tuple():将一个可迭代对象转换成元组
dict():通过相应的方式创建字典。
abs():返回绝对值
sum():求和
reversed():将一个序列翻转,返回翻转序列的迭代器。与列表的方法l1 .reverse()
区分.
complex:创建一个值为real+imag*j的复数;转换一个str或int为复数,如果第一个参数为str则不需要传递第二个参数。(复数:complex)
print(complex('1')) #(1+0j)
bin:将十进制数转换为二进制字符串并返回。
oct:将十进制数转换为八进制字符串并返回。
hex:将十进制数转换为十六进制字符串并返回。
divmod:计算除数与被除数的结果,返回一个包含商和余数的元祖(a//b,a%b)
round:保留浮点数的位数,默认保留整数。
pow:求x**y的次幂,并可以对所求结果对第三个参数取余
print(pow(2,2)) #2**2 4
print(pow(2,2,3)) #(2**2)%3 1
bytes:用于不同编码之间的转换。
s1 = '你好'
bs1 = s1.encode('utf-8')
print(bs1)
#b'\xe4\xbd\xa0\xe5\xa5\xbd'
s2 = bs1.decode('utf-8')
print(s1)
#你好
s3 = '你好'
bs2 = bytes(s3,encoding='utf-8')
print(bs2)
#b'\xe4\xbd\xa0\xe5\xa5\xbd'
bs3 = str(bs2,encoding='utf-8')
print(bs3)
#你好
ord():输入字符找该字符编码的位置。(如果在ASCII码中就用ASCII码,否则用Unicode)
chr():输入位置数字找出其对应的字符。(如果在ASCII码中就用ASCII码,否则用Unicode)
repr():返回一个对象的string形式。(str带有引号的形式),在格式化输出时常用(%r)。
s1 = 'python'
print('i love %r'%(s1)) #i love 'python'
print():源码分析:print(self, *args, sep=' ', end='\n', file=None,flush=False):
file: 默认是输出到屏幕,如果设置为文件句柄,输出到文件
sep: 打印多个值之间的分隔符,默认为空格
end: 每一次打印的结尾,默认为换行符
flush: 立即把内容输出到流文件,不作缓存
print(1,2,3) #1 2 3
print(1,2,3,sep='@') # 1@2@3
print(1,2,3,end='') #不换行
all():可迭代对象中,全为True才是True。
any():可迭代对象中,有一True即为True。
zip(): 拉链方法;函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元祖组成的内容,如果各个迭代器的元素个数不一致,则按照长度最短的返回。
lst1 = [1,2,3]
lst2 = ['a','b','c','d']
lst3 = (11,12,13,14,15)
for i in zip(lst1,lst2,lst3):
print(i)
#(1, 'a', 11) (2, 'b', 12) (3, 'c', 13)
min():求最小值,可以与函数结合(key:自动将可迭代对象中的每个元素按照顺序传入key对应的函数中,然后以返回值比较大小,key=一定是函数名,不能加(),。min/max默认会按照字典的键去比较大小,但可以自己规定。
#以绝对值的方式取最小值
l1 = [1,2,-1,-5,3]
def func(s):
return abs(s)
print(min(l1,key=func)) #1
#也可以直接使用匿名函数:
print(min(l1,key=lambda s:abs(s))) #1
dic = {'a':3,'b':2,'c':1}
min(dic) #a 默认以键排序,返回键
#以值比较:
print(min(dic,key=lambda s:dic[s])) #c 以值排序,返回键(返回的是循环的元素,而不是经函数转换后比较的值。
max():求最大值,可以与函数结合,同min()。
sorted():排序函数;语法: sorted(iterable,key=None,reverse=False)。key: 排序规则(排序函数),返回列表。在sorted内部会将可迭代对象中的每一个元素传递给这个函数的参数.根据函数运算的结果进行排序reverse: 是否是倒叙,True:倒叙;False:正序
lst = [1,3,2,5,4]
lst2 = sorted(lst)
print(lst) # 原列表不会改变
print(lst2) # 返回的新列表是经过排序的
lst3 = sorted(lst,reverse=True)
print(lst3) # 倒叙
#字典使用sorted排序
dic = {1: 'a',3: 'c',2: 'b'}
print(sorted(dic)) #[1,2,3] 字典排序返回的就是排序后的key
#和函数组合使用
# 定义一个列表,然后根据一元素的长度排序
lst = ['1','111','11','1111']
# 计算字符串的长度
def func(s):
return len(s)
print(sorted(lst,key=func)) #['1','11','111','1111']
lst = [{'id': 1,'name': 'a','age': 18},
{'id': 2,'name': 'b','age': 17},
{'id': 3,'name': '3','age': 16},]
# 按照年龄对学生信息进行排序
print(sorted(lst,key=lambda e: e['age']))
filter():筛选过滤,返回一个迭代器(可与列表推导式的筛选模式进行对比);语法: filter(function,iterable),function: 用来筛选的函数,在filter中会自动的把iterable中的元素传递给function,然后根据function返回的True或者False来判断是否保留此项数据
lst = [{'id':1,'name':'a','age':18},
{'id':2,'name':'b','age':17},
{'id':3,'name':'c','age':16},]
ls = filter(lambda e:e['age'] > 16,lst)
print(list(ls))
#[{'id': 1, 'name': 'alex', 'age': 18},{'id': 1, 'name': 'wusir', 'age': 17}]
map():映射函数,返回一个迭代器(可与列表推导式的循环模式对比);语法: map(function,iterable) 可以对可迭代对象中的每一个元素进映射,分别取执行function。
#例1;计算列表中每个元素的平方,返回新列表
lst = [1,2,3,4,5]
print(map(lambda s:s*s,lst)) #<map object at 0x000002B2A4F04B88>
print(list(map(lambda s:s*s,lst)))
#例2;计算两个列表中相同位置的数据的和
lst1 = [1, 2, 3, 4, 5]
lst2 = [2, 4, 6, 8, 10]
print(list(map(lambda x, y: x+y, lst1, lst2)))
reduce():reduce(函数名,可迭代对象) # 这两个参数必须都要有,缺一个不行,在Python2.x版本中recude是直接 import就可以的, Python3.x版本中需要从functools这个包中导入。
from functools import reduce
def func(x,y):
return x + y
ret = reduce(func,[1,2,3])
print(ret) # 结果 6
#reduce的作用是先把列表中的前俩个元素取出计算出一个值然后临时保存着,接下来用这个临时保存的值和列表中第三个元素进行计算,求出一个新的值将最开始临时保存的值覆盖掉,然后在用这个新的临时值和列表中第四个元素计算.依次类推。注意:我们放进去的可迭代对象没有更改
#现在有[1,2,3,4]想让列表中的数变成1234
l = reduce(lambda x,y:x*10+y,[1,2,3,4])
print(l)
闭包、装饰器
全局变量,数据不安全。使用局部变量,保证数据的安全。当内层函数对外层函数非全局变量的引用(使用)时,就会形成闭包。被引用的非全局变量也称作自由变量,这个自由变量会与内层函数产生一个绑定关系,令自由变量不会再内存中消失。闭包现象只能存在函数的嵌套中。
判断一个函数有没有自由变量:
def func1():
l1= []
def func2(num):
l1.append(num)
return l1
return func2
a = func1()
# 函数名.__code__.co_freevars 查看函数的自由变量
print(a.__code__.co_freevars) # ('l1',)
# 函数名.__code__.co_varnames 查看函数的局部变量
print(a.__code__.co_varnames) # ('num',)
# 函数名.__closure__ 获取具体的自由变量对象,也就是cell对象。
print(a.__closure__)
#(<cell at 0x000001EE151AC738: list object at 0x000001EE135851C8>,)
# cell_contents 自由变量具体的值
print(a.__closure__[0].cell_contents) # []
装饰器:完全遵循开放封闭原则,即在不改变原函数的代码以及调用方式的前提下,为其增加新的功能。(装饰器的本质是闭包)python提出了一个‘语法糖’的概念。在编写了装饰器后,需要将装饰器代码放在所有代码的前方。当要对装饰器函数调用时,在要装饰函数的前方使用@+装饰器函数名
标准版的装饰器:
def wrapper(f):
def inner(*arg,**kargs):
'''添加额外的功能:执行被装饰函数之前的操作'''
ret = f(*arg,**kargs)
'''添加额外的功能:执行被装饰函数之前的操作'''
return ret
return inner
#装饰器的调用
@wrapper
def func():
pass
自定义模块
模块的本质就.py文件,封装语句的最小单位。模块的分类:内置模块(200种左右)、第三方模块(6000多种)、自定义模块。当python脚本/模块运行时,python解释器会自动将一些模块、函数加载到内存。可用import sys print(sys.modules)
查看
自定义模块:
-
编写自定义模块开头最好用多行注释说明模块内容。
-
模块中出现的变量、函数定义、类等称为模块的成员。
-
模块(.py文件)的运行方式:
- 脚本方式:直接用解释器执行。
- 模块方式(导入方式):被其他的模块导入,为导入它的模块提供资源(变量、函数定义、类定义等)。
-
模块被其他模块导入时,会将模块中的所有代码加载到内存,其中的可执行语句被会立即执行。因此为了方便调试和使用,可用
__name__
属性。将print(__name__)
编写在模块中时,以脚本方式运行打印的是字符串__main__
,以被导入的方式运行时,会打印出模块名。因此模块应包含if __name__=='__main__':
以用来判断是脚本方式运行还是导入方式,此时当模块被导入时可执行语句不会直接运行。def func(): ...... def main(): pass if __name__=='__main__': main()
导入模块的方式:
-
import xxx
或import xxx,yyy,....
导入一个模块或导入多个模块。经常将import os,sys
这两个模块放在一块导入。可以使用别名(alias,缩写为as)导入:import xxx as z
导入xxx模块重命名为z。当运行至此导入模块方法代码时会在内存全局命称空间中开辟以模块名命名的新的名称空间,并将模块中的所有成员加载至命称空间中。被导入的每个模块都有独立的命称空间。
-
from xxx import y
或from xxx import a,b,c,......
:从某个模块中导入指定的成员或导入多个成员。from xxx import yyy as z
导入xxx模块将成员名重命名为z。当运行至此导入模块方法代码时会在脚本的全局命称空间中创建导入的成员的变量,因此不用使用
模块名.成员名
调用,但用此方法可能会导致命名冲突,后者将前者覆盖。导入后内存全局命称空间中开辟以模块名命名的新的名称空间,变量的内存地址的指向关系仍然不会改变,每个模块仍都有独立的命称空间。 -
from xxx import *
:默认从某个模块中导入全部可导入的成员。配合__all__
使用,被引用的模块中编写__all__=['','',...]
列表中是可被导入的成员。但__all__
只对此种导入方法起作用,用于表示模块可以被外界使用的成员,元素是成员名组成的字符串,默认不写是可以导入全部成员。
系统导入模块的搜索路径,以import time
示例:先在内存中查看是否有以该模块名命名的命称空间,如果之前成功导入过某个模块,会直接使用已经存在的模块。若没有则再内置模块路径中(在python安装路径中lib和site-packages文件夹下)寻找。若仍没有,就会在sys.path
中寻找。
sys.path:查看sys.path内容,用cmd运行:import sys print(sys.path)
打印出的列表第一个元素是当前执行脚本的路径。列表动态可修改因此可将自定义模块文件夹所在的绝对路径添加到sys.path中以便导入:
import sys
sys.path.append('模块文件夹路径')
在不同的目录下相对导入自定义模块:
相对导入:针对某个项目中的不同模块之间进行导入,称为相对导入(模块间必须有一个同一个文件夹)。相对导入只有一个语法:from 相对路径 import xxx
相对路径:包含了点号的一个相对路径。
.:表示当前的路径。
..:表示的是父路径
...:表示的是父路径的父路径
..x.y:表示的是父路径下x文件夹下的y文件(夹)
举例:在python文件夹下有t1和t2两个文件夹,t1和t2文件夹下分别有pt1.py和pt2.py两个模块。python文件夹在WorkSpace文件夹下,WorkSpace下有一个main.py文件。
#相对导入(在pt1.py文件中编写):
#1.将pt1作为对外界的接入口:
from ..t2 import pt2 #..:从当前的路径(不包含当前文件,即/WorkSpace/python/t1)的父目录(/WorkSpace/python/)下找t2,在从t2中找pt2。
#测试相对导入(在main.py文件中编写):
import os,sys
sys.path.append(os.path.dirname(__file__)) #把项目所在的父路径加到sys.path中。
from python.t1 import pt1
#使用pt1.py模块文件导入的pt2.py模块中的成员:
pt1.pt2.成员名 #但不推荐这样写。容易向外界暴露pt2模块。
#更改方法(真正的相对导入):
#相对导入(在pt1.py文件中编写):
#1.将pt1作为对外界的接入口:
from ..t2.pt2 import * #直接导入pt2模块
#测试相对导入(在main.py文件中编写):
import os,sys
sys.path.append(os.path.dirname(__file__)) #把项目所在的父路径加到sys.path中。
from python.t1 import pt1
#使用pt1.py模块文件导入的pt2.py模块中的成员:
pt1.成员名 #成员名:可以是pt1和pt2模块的成员。
#不用相对导入(不推荐):
#1.在pt1模块下编写:
import os,sys
sys.path.append(as.path.dirname(os.path.dirname(__file__))+'/t2')
from pt2 import *
常用模块
使用导入的模块是否要在其后加():如果是一个类(class)或者是一个函数(function)就要加(),如果是一个属性就不要加括号。
random模块
1)random模块(pseudo-random,伪随机数):提供了随机数获取的方法
1)random.random():获取[0.0,1.0)范围内的浮点数。
2)random.randint(a,b):获取[a,b]范围内的一个整数。
3)random.uniform(a,b):获取[a,b]范围内的一个浮点数数。
4)random.shuffle(x):把参数指定的数据中的元素打乱,参数必须是一个可变的数据类型。没有返回值(因为是直接将x打乱,调用改函数后x会被改变,与append无返回值原因相同。)(不支持元祖,可用sample打乱)
5)random.sample(x,k):从x中随机抽取k个数据,组成一个列表返回。
6)random.randrange(start,stop,step):生成一个[start,stop)之间以step为步长的随机整数。默认步长为1。
7)random.seek(a):设置初始化随机数种子。a,随机数种子,可以是整数或浮点数。使用random库产生随机数不一定要设置随机数种子,如果不设置,random库默认以系统时间产生当做随机数种子。设置随机数种子的好处是可以重复在现相同的随机数序列。
l1 = [1,2,3,4,5,6,] #列表是有序的
s1 = {1,2,3,4,5,6,}
s2 = 'wfwhgfwqnbvc阿尔天花板vc'
t1 = (1,2,3,4,5,6,)
import random
random.seed()
print(random.random())
print(random.uniform(1,8))
print(random.randint(2,8))
print(random.shuffle(l1)) #只能用于有下标类型,并且可以用x[i],x[j]=x[j],x[i]互换,dict、set、tuple不行。
print(l1)
random.shuffle(s2)
print(s2)
s3 = random.sample(t1,len(t1)) #取样,
print(t1)
time模块
封装了获取时间戳和时间戳与字符串形式的一些方法,时间戳:从时间元年(1970年,1月,1日,00:00:00)到现在经过的秒数(毫秒数,不同系统/编程语言不一样。)
import time
# 获取时间戳:
print(time.time())
# 默认使用当前时间戳,
# 获取格式化时间对象(方法:gmtime()、localtime()),格式化时间对象:struct_time:
print(time.gmtime()) #接受参数为时间戳,默认不写使用当前时间戳,获取格林威治(GMT)时间。
print(time.localtime()) #接受参数为时间戳,默认不写使用当前时间戳,获取当地时间,tm_hour与格林威治时间(时区差)不同。
# 格式化时间对象和时间字符串(str)之间的转换。time.strftime(format,str)
a = time.localtime()
print(time.strftime('%Y-%m-%d %H:%M:%S',a)) #接受两个参数,第一个是时间格式,第二个是格式化时间对象(默认不写用当前的时间戳的格式化时间对象)。
# 时间字符串转换为时间对象(time.strptime(str,format)):
print(time.strptime('2000 1 1','%Y %m %d')) #不指定时间用默认值(小时分钟等用0,月份天等用1)
# 格式化时间对象转换为时间戳:time.mktime()
print(time.mktime(time.localtime()))
# 暂停当前程序:time.sleep() 参数为秒
time.sleep(2) #暂停2秒
datetime模块
封装了一些日期和时间相关的类。主要用于数学计算
date类(年月日):
#date类
d = datetime.date(2010,10,10)
print(d) #2010-10-10
print(d.year) #2010
print(d.month) #10
print(d.day) #10
time类(时分秒):
#time类
t = datetime.time(10,11,12)
print(t)
print(t.hour)
print(t.minute)
print(t.second)
datetime类
dt = datetime.datetime(2010,10,10,11,11,11)
print(dt)
print(dt.year)
timedelta类: 参与数学运算,创建时间对象(只能和date,datetime,timedelta进行运算),会产生进位,和时间段进行运算的结果类型和另一个被操作的类型相同。
td = datetime.timedelta(seconds=3)
d = datetime.datetime(2000,10,10,10,10,59)
res = d+td
print(res)
练习:随便给出一年,计算2月份有多少天。
import datetime
#1.首先创建出指定年份的3月1号,然后让它往前走一天。
year = int(input("输入年份:"))
#2. 创建指定年份的date对象。
d = datetime.date(year,3,1)
dt = datetime.timedelta(days=1)
res = d-dt #和时间段进行运算的结果类型和前方被减类型相同。
print(res.day)
os模块
和操作系统相关的操作被封装在这个模块中。
-
和文件相关的:重命名、删除、
import os #删除文件 os.remove() #参数为文件的路径 #重命名文件 os.rename() #两个参数,第一个为文件路径,第二个为文件新名 #删除目录,必须是空目录,在程序中删除不会放在回收站中。 os.removedirs() #一个参数,目录的路径 #使用shutil模块可以删除带内容的目录。 import shutile shutile.rmtree() #一个参数,文件夹目录 os.getcwd() #可查看当前的目录 os.chdir(‘指定目录’) #可切换目录
-
和路径相关的操作,被封装到另一个子模块中:
os.path
绝对路径:从盘符开始定位的路径;相对路径:从当前文件定位的路径
exists(path) 判断路径是否存在 若文件不存在则为False isdir(s) 判断是否为一个目录 若文件不存在则为False isfile() 判断是否是一个文件 若文件不存在则为False 以下方法不会判读文件是否存在 dirname(path) 取一个路径前的目录(父目录),不会判断目录是否存在, basename(path) 取一个路径中最后的部分 split(path) 分割路径,返回一个二元祖,第一个元素为路径前的(父目录),第二个为路径中最后的部分。 join(path,paths) 合并路径。 abspath(path) 将路径变为绝对路径 isabs() 判断一个路径是否为绝对路径
import os res = os.path.dirname(r'd:/aaa/bbb/ccc/text.py') print(res) #d:/aaa/bbb/ccc res = os.path.basename(r'd:/aaa/bbb/ccc/text.py') print(res) #text.py res = os.path.join('d:\\','aaa','bbb','cc') #有一个转义字符 print(res) #d:\aaa\bbb\cc res = os.path.abspath(r'd:\aaa\bbb\cc') print(res) #D:\aaa\bbb\cc res = os.path.abspath(r'\aaa\bbb\cc') #如果是\开头的路径,默认是在当前盘符下。 print(res) #D:\aaa\bbb\cc res = os.path.abspath(r'aaa\bbb\cc') #如果不是\开头,则是当前脚本的路径。 print(res) #D:\WorkSpace\Python\text1\aaa\bbb\cc
使用os模块获取一个文件路径的父路径:
import os os.path.dirname(__file__)
,__file__
:获取模块的路径。import os os.__file__
sys模块
提供了解释器使用和维护的变量和函数;没有提供源码,用c语言编写直接集成在解释器上;默认会导入os模块,但若要使用os模块仍需import os
。
-
sys.argv
:以当前脚本方式执行程序时,从命令行获取参数。argv[0]
表示的是当前正在执行的脚本名,argv[1]
表示第一个参数,以此类推。import sys print("脚本名:",sys.argv[0]) print("第一个参数:",sys.argv[1]) #在命令行运行,传入两个参数,会将两个参数打印出来
-
sys.path
系统寻找模块的路径,可以通过PYTHONPATH来进行优化。由于是程序执行的时候进行初始化的,所以路径的第一项path[0]始终是调用解释器的脚本所在的路径,如果是动态调用的脚本,或者是从标准输入读取到的脚本命令,则path[0]是一个空字符串,程序中可以随时对这个路径进行修改,已达到动态添加模块路径的目的。 -
sys.modules
:以字典形式返回系统已经加载的模块。常作为是否重新重新加载模块的判断。
json模块
将数据结构直接转换为字符串用str()
可以,但再将字符串数据转换为原先的数据结构就会出现问题。
l1 = ['ab','cd']
s1 = str(l1)
print(s1) #['ab', 'cd']
print(list(s1)) #['[', "'", 'a', 'b', "'", ',', ' ', "'", 'c', 'd', "'", ']']