VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • python基础总结(4)

:默认从某个模块中导入全部可导入的成员。配合__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模块

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', "'", ']']

JavaScript Object Notation:Java脚本兑现标记语言。已经成为一种简单的数据交换格式。将数据转换成特殊字符串,不同语言都遵循的一种数据转化格式,用于储存dump()和load()或dumps()和loads()或网络传输dumps()和loads()

json序列化:

import json
s = json.dumps([1,2,3,4,])  #将指定的对象转换成json格式的字符串,仍然放在内存中
print(s,type(s))	#[1, 2, 3, 4] <class 'str'>

#元祖序列化后变成列表
import json
s = json.dumps((1,2,3,4,)) 
print(s,type(s))	#[1, 2, 3, 4] <class 'str'>

#集合不可一被json序列化

#将结果直接写到文件中:json.dump(obj,fb)
with open('a.txt',mode='at',encoding='utf-8') as f:
    json.dump(['1,2,3,'],f)

json反序列化:

import	json
res = json.dumps([1,2,3,])
lst = json.loads(res)

#从文件中反序列化:json.loads(fb)
with open('a.txt',encoding='utf-8') as f:
    res = json.load(f)

dump()和load()只能一次性写,一次性读。把需要序列化的对象,通过dumps()和loads()的方式,可实现多次读或写,写入时要换行,才能读出再转化。

with open('a.txt',mode='wt',encoding='utf-8') as f:
    for i in range(10):
		f.write(json.dumps()+'\n')

with open('a.txt',encoding='utf-8') as f:
    for i in f:
    	json.loads(i.strip())	#	或json.loads(i),默认去除换行

pickle模块

可将python中所有的数据类型转换成字节串

元祖在pickle中转换不会改变类型。

pickle也可以转换set类型

pickle中dump()和load()可以多次读写一个文件dump(s,f)可以写入python中的任何对象(变量、函数、类等)

import pickle
bys = pickle.dumps((1,2,3))  #转化为字节
res = pickle.loads(bys)
print(type(res),res) 	#<class 'tuple'> (1, 2, 3)

#把pickle序列化内容写入文件中:
with open('b.txt',mode='wb') as f:
    pickle.dump([1,2,3],f)
    
    
#从文件中反序列化pickle数据:
with open('b.txt',mode='rb') as f:
    pickle.load(f)

pickle与json的比较

json:

  1. 不是所有的数据类型都可以序列化
  2. 不能多次对同一个文件序列化
  3. json数据可以跨语言。
  4. json序列化只支持部分python数据结构:dict、tuple、int、float、True、False、None

pickle:

  1. 所有的python类型都能序列化,结果为字节串。
  2. 可以多次对同一个文件序列化
  3. 不能跨语言,只能在python中使用。

hashlib模块

封装一些用于加密的类。加密的目的:用于判断和验证,而非解密。给一个数据进行加密,用另个加密的结果和第一次加密的结果进行对比,如果加密结果想同,说明原文相同。

特点:

  • 把一个大的数据切分成不同的块,分别对不同的块进行加密,再汇总的结果和直接对整体数据加密的结果是一致的。
  • 单向加密,不可逆。
  • 原始数据的一点小的变化,将导致加密结果非常大的差异。

md5加密算法:

import hashlib
#获取一个加密对象
m = hashlib.md5()
#使用加密对象的update进行加密
m.update(b'abc')	#将abc变为字节,若有中文则为'abc'.encode('utf-8')
#通过hexdigest()获取加密。
res = m.hexdigest()
print(res)	#900150983cd24fb0d6963f7d28e17f72

给一个数据加密的步骤:

  1. 获取一个加密对象,不只是有md5,还有sha系列sha224', 'sha256', 'sha384', 'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512', 'sha512'等,随着sha系列数字越高,加密越复杂,。在创建加密对象时,可以指定参数,使加密程度更高。

    import hashlib
    m = hashlib.md5('abc'.encode('utf-8'))
    m.update('qaz'.encode('utf-8'))
    print(m.hexdigest())
    
  2. 使用加密对象的update()方法进行加密。加密对象可以调用多次(即为把一个大数据切分成小数据,再把小数据进行累次加密,不是对同一个数据多次加密)。都是对字节进加密。相同的加密对象将字节转化成固定长度的字符串。

  3. 通常通过hexdigest()获取加密字符串,也可以通过digest()获取加密字节串。

    不同加密算法的加密结果长度不同,随着加密结果的变长,加密时间也会变长。

    #注册和登录程序
    import hashlib
    def register():
        username = input('输入用户名:')
        passwd = input("输入密码:")
        get_passwd = get_md5(passwd)    #加密
        with open('login',mode='at',encoding='utf-8') as f:     #写入文件
            f.write(f'{username}|{get_passwd}\n')
    
    def login():
        username = input('输入用户名:')
        passwd = input('输入密码:')
        get_passwd = get_md5(passwd)
        res = f'{username}|{get_passwd}\n'
        with open('login',mode='rt',encoding='utf-8') as f:
            for line in f:
                if res == line:
                    return True
            else:return False
    
    def get_md5(passwd):
        m = hashlib.md5('12')	#再次加密
        m.update(passwd.encode('utf-8'))
        return m.hexdigest()
    
    while True:
        op = input('1.注册 2.登录 3.退出')
        if op == '1':
            register()
        elif op == '2':
            res = login()
            if res:
                print('登录成功')
            else:
                print('登录失败,请重新登录')
        elif op == '3':
            break
        else:print("您输入的有误,请重新输入")
    

文件的校验:

Linux中一切皆文件:文本文件,非文本文件,音频,视频,图片……。无论下载的视频还是国外的软件往往都会有一个md5值。

collections模块

封装了一些常用的容器类。

namedtuple():命名元祖,可以使用属性的方式引用元祖中的数据。

import collections as co:
#namedtuple()的返回值是一个类
Rectangle = co.namedtuple('Rectangle_class',['length','width']) #第一个参数是对类名的说明信息,不能有空格。namedtuple()的返回值是赋值给了自定的类名。
r = Rectangle(10,5)
#通过属性访问元祖的元素
print(r.length)
print(r.width)
#通过引所的方式访问元素
print(r[0])

defaultdict():默认值字典

#defaultdict():(自定义)函数(不能有参数)充当第一个参数
d = co.defaultdict(lambda :'hello',name='aa',age='10')
print(d['na'])	#hello      若无要查询的键,不会报错,会根据函数返回一定的值,且会自动将此键值增加至字典中
print(d)
#defaultdict(<function <lambda> at 0x000001F90D30D378>, {'name': 'aa', 'age': '10', 'na': 'hello'})

Counter():计数器,返回值是字典,必须使用可哈希的数据。

c = co.Counter('asasasasaszszxaxzsxazsx')
print(c)	#Counter({'s': 8, 'a': 7, 'z': 4, 'x': 4})
print(c.most_common(3))		#[('s', 8), ('a', 7), ('z', 4)]

re模块

findall():返回所有符合匹配结果的列表,只有一个元祖元素,每个分组是元祖中的每个元素。如果正则进行分组,则只显示分组里的内容。若不想让每个分组返回;取消分组优先,在分组括号中增加?:

search():返回一个对象(变量),需和group()配合。如果进行分组,则只显示第一个分组里的内容,但可以通过group(n)获取第n个分组的内容(n>0),默认为0,返回所有的分组结果。

设置参数flags=re.S可让.匹配任意内容,包括换行符。

import re
ret = re.search('(d+)\w','123123adas1213as')
if ret:    #若ret为None直接打印ret.group()就会报错。
    print(ret.group())

split():可以根据正则表达式切割字符串,返回分组,若给正则加上分组,则会将分组中匹配的内容保留至列表中。

sub():替换。re.sub('\d','a','123qwe21',1)将数字替换成a,只替换1次。

subn():替换,返回二元祖。第一个为替换结果,第二个为替换次数。

match():只匹配开头,通过group()取值,相当于使用search()方法在正则表达前使用^。用来规定字符串必须是什么。

时间:完成一个程序所需要的代码行数;在执行代码的过程中,底层程序是如何工作的。

空间:占用的内存条资源,程序的执行效率。

compile():假如同一个正则表达式要被多次使用,可用re.compile('正则表达式')可节省了多次解析同一个正则表达式的时间。从时间上提高了效率。如果不重复使用正则,则不会节省时间。

finditer():将正则表达式的匹配所有的结果变成一个迭代器,用.group()每个获取结果。节省了空间。

import re
ret = re.compile('\d')
res = ret.finditer('qaq112qsx123sxa')
for i in res:
    print(r.group())

分组命名:在分组中取名?P<分组名>将名字放在<>之间。可以用group('分组名')获取。分组匹配的内容可以被引用。

import re
exp = '<h1>123qdwdcasd</h1>'
ret = re.search('<(?P<tag>\w+)>.*?</(?P=tag)>',exp)		#第二个分组引用的是第一个分组匹配的内容。
print(ret)	

分组间也可以用\n引用:n为要引用的第几个分组。

import re
exp = '<h1>123qdwdcasd</h1>'
ret = re.search(r'<(?P<tag>\w+)>.*?</\1>',exp)		#在python中`\1、\2、\3等是有特殊意义的,因此要表示在正则中的意义需要转义,即加r或\
ret = re.search('<(?P<tag>\w+)>.*?</\\1>',exp)	

shutil模块

import shutil

# 拷贝文件,shutil.copy2('原文件', '现文件')
shutil.copy2('file', 'temp')

# 拷贝目录,shutil.copytree("原目录", "新目录",ignore=shutil.ignore_patterns(*args))
#ignore,忽略要copy的文件
shutil.copytree("/Users/jingliyang/PycharmProjects", "logging模块2", ignore=shutil.ignore_patterns('*.py')) #*.py:所有的以.py结尾的。

# 删除目录,shutil.rmtree("temp", ignore_errors=True)	ignore_errors:是否忽略一些错误。
shutil.rmtree("logging模块2", ignore_errors=True)

# 移动文件/目录,并可以重命名。
shutil.move("logging模块", "logging2", copy_function=shutil.copy2)

# 获取磁盘使用空间
total, used, free = shutil.disk_usage(".") .:查看当前磁盘的空间,也可以用:'c:\\' 
print("当前磁盘共: %iGB, 已使用: %iGB, 剩余: %iGB"%(total / 1073741824, used / 1073741824, free / 1073741824))

# 压缩文件,shutil.make_archive('压缩文件夹的名字', 'zip','待压缩的文件夹路径')
shutil.make_archive('logging2', 'zip','/Users/jingliyang/PycharmProjects/面试题/常用模块/随机数')

# 解压文件,shutil.unpack_archive('zip文件的路径.zip','解压到目的文件夹路径')
shutil.unpack_archive('/Users/jingliyang/PycharmProjects/面试题/常用模块/shutil模块/logging2.zip','/Users/jingliyang/PycharmProjects/面试题/常用模块/shutil模块/tmp')

logging模块

log:用来记录用户的行为,以便数据分析,操作审计;用来排查代码中的错误。

基本配置: