3.1 上章补充-bytes类型

数据存到硬盘,硬盘只能存二进制2进制 --》十进制 --asscii/gbk/utf-8/ unicode文字 --》utf-8/gbk  --》二进制
图片 --》jpg/png  --》二进制
音乐 --》mp3/wav --》二进制
视频 --》mp4/mov --》二进制bytes类型,以16进制表示,2个十六进制数构成一个byte,以b''来标识py3 文件默认编码utf-8
pycharm 默认加载文件都是utf-8编码b binary(二进制)
1.字符存硬盘 要变成bytes
2.网络传输 字符要变成bytes编码与解码:编码:s.encode("utf-8") 以utf-8编码成二进制解码:s.decode("utf-8") 从二进制解码成Unicode str编码的转换:把文字从一种编码转成另外一种编码,从gbk 转成utf-8gbk --> Unicode --> utf-82进制模式打开文件有wb 二进制创建rb 二进制读ab 二进制追加

3.2 上章补充-深浅copy

dict、list、set、
潜copy:s1 = s.copy()
深copy: s4 = copy.deepcopy(s)

3.3 函数来了:

函数是什么:define 定义函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可特性:减少重复代码使程序变的可扩展使程序变得易维护语法定义:def test():  # 函数名print("hello world")test()  # 函数的调用可带参数:def test(a, b):res = a**breturn res  # 返回值,意味着函数终止n = test(5, 8)print(n)函数的参数:形参、实参:默认参数:关键参数:位置参数 > 关键参数 > 默认参数位置参数:非固定参数:在定义函数时,不确定后面调用时,会传递多少个参数进来def register(name, age, major, country='cn', *args, **kwargs):print(args, kwargs)函数的返回值:def test(name, age):if age > 20:return True  # 返回值else:return False # 返回值全局变量和局部变量:全局变量:作用域(即有效范围)是整个程序。局部变量:作用域是定义该变量的函数。变量的查找顺序:局部变量>全局变量就是想在函数里修改全局变量怎么办?global name #声明一个全局变量global name:在函数里声明全局变量name ,意味着最上面的name = “Alex Li”即使不写,程序最后面的print也可以打印name。

3.4 嵌套函数&匿名&高阶函数:

嵌套函数:函数里不仅可以写代码,还可以嵌套函数name = "小猿圈"def change():name = "小猿圈,自学编程"def change2():# global name  如果声明了这句,下面的name改的是最外层的全局变层name = "小猿圈,自学编程不要钱" #这句注释掉的话,下面name打印的是哪个值?print("第3层打印", name)change2()  # 调用内层函数print("第2层打印", name)change()print("最外层打印", name)通过上面的例子,我们理解了,每个函数里的变量是互相独立的,变量的查找顺序也是从当前层依次往上层找匿名函数:匿名函数就是不需要显式的指定函数名calc = lambda x,y:x**yprint(calc(2,5)可以搭配其他函数使用:res = map(lambda x:x**2,[1,5,7,4,8])for i in res:print(i)高阶函数:变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。def get_abs(n):if n < 0 :n = int(str(n).strip("-"))return ndef add(x,y,f):return f(x) + f(y)res = add(3,-6,get_abs)print(res)只需满足以下任意一个条件,即是高阶函数:接受一个或多个函数作为输入return 返回另外一个函数

3.5 递归:

自己调用自己
递归的执行过程:def calc(n):n = int(n/2)print(n)if n > 0:calc(n)print(n)calc(10)
输出:52100125
为什么输出是这样呢?
函数在每进入下一层的时候,当前层的函数并未结束,它必须等它调用的下一层函数执行结束返回后才能继续往下走。
所以最下面的那句print(n)会等最里层的函数执行时才会执行,然后不断往外退层,所以会出现0、1、2、5的效果递归的特性:1.必须有一个明确的结束条件2.每次进入更深一层递归时,问题规模相比上次递归都应有所减少3.递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)练习题:
用递归实现2分查找的算法,以从列表a = [1,3,4,6,7,8,9,11,15,17,19,21,22,25,29,33,38,69,107]
查找指定的值。

3.6 内置函数:

Python解释器自带的函数:
abs()       # 求绝对值
ascii       # 返回一

3.7 名称空间:

又名name space, 顾名思义就是存放名字的地方,存什么名字呢?举例说明,若变量x=1,1存放于内存中,
那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方名称空间有4种:locals:函数内部的名字空间,一般包括函数的局部变量以及形式参数enclosing function:在嵌套函数中外部函数的名字空间, 若fun2嵌套在fun1里,对fun2来说,fun1的名字空间就enclosing.globals:当前的模块空间,模块就是一些py文件。也就是说,globals()类似全局变量。builtins: 内置模块空间,也就是内置变量或者内置函数的名字空间,print(dir(builtins))可查看包含的值。不同变量的作用域不同就是由这个变量所在的名称空间决定的。作用域即范围:全局范围:全局存活,全局有效局部范围:临时存活,局部有效查看作用域方法 globals(),locals()作用域查找顺序:L E G Blocals -> enclosing function -> globals ->builtins示例:
level = 'L0'
n = 22
def func():level = 'L1'n = 33print(locals())def outer():n = 44level = 'L2'print("outer:",locals(),n)def inner():n = 55level = 'L3'print("inner:",locals(),n) #此处打印的n是多少?inner()outer()
func()
输出:
{'n': 33, 'level': 'L1'}
outer: {'level': 'L2', 'n': 44} 44
inner: {'level': 'L3', 'n': 44} 44

3.8 闭包:

  关于闭包,即函数定义和函数表达式位于另一个函数的函数体内(嵌套函数)。而且,这些内部函数可以访问它们所在
的外部函数中声明的所有局部变量、参数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成
闭包。也就是说,内部函数会在外部函数返回后被执行。而当这个内部函数执行时,它仍然必需访问其外部函数的局部
变量、参数以及其他内部函数。这些局部变量、参数和函数声明(最初时)的值是外部函数返回时的值,但也会受到内
部函数的影响。示例:def outer():name = 'alex'def inner():print("在inner里打印外层函数的变量",name)return inner # 注意这里只是返回inner的内存地址,并未执行f = outer() # .inner at 0x1027621e0>f()  # 相当于执行的是inner()注意此时outer已经执行完毕,正常情况下outer里的内存都已经释放了,但此时由于闭包的存在,我们却还可以调用
inner, 并且inner内部还调用了上一层outer里的name变量。这种粘粘糊糊的现象就是闭包。闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域

3.9 装饰器:

1.装饰器符号“@”属于语法糖,什么意思呢?就是说,我不按照@装饰器的语法要求来写,而是按照一般python的语法要求来写完全可以。那么用@装饰器的格式来写的目的就是为了书写简单方便
2.装饰器的作用是什么呢? 简单的理解就是:装饰原有的函数。什么意思呢?比如有一个函数func(a, b),它的功能是求a,b的差值,我现在有一个需求,就是想对函数功能再装饰下,求完差值后再取绝对值,但是不能在func函数内部实现,这时候就需要装饰器函数了,比如func = decorate(func)函数,将func函数作为参数传递给decorate函数,由decorate来丰富func函数,丰富完成后再返回给func,此时func的功能就丰富了。软件开发中的一个原则“开放-封闭”原则:封闭:已实现的功能代码块不应该被修改开放:对现有功能的扩展开放

4.0 列表生成式:

略叼青年版:a = map(lambda x:x+1, a)for i in a:print(i)装逼青年版:a = [i+1 for i in range(10)]print(a)这样的写法就叫做列表生成式,有什么用呢?装逼用,哈哈,写出来显的高级,效果跟上面的都一样哈。

4.1 生成器:

生成器:generator
在Python中,这种一边循环一边计算后面元素的机制,称为生成器。要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了
一个generator:(x*x for x in range(10))
如果要一个一个打印出来,可以通过next()函数获得generator的下一个返回值函数生成器:generator非常强大。如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。实现100以内的斐波那契数代码:a,b = 0,1n = 0  # 斐波那契数while n < 100:n = a + ba = b # 把b的旧值给到ab = n # 新的b = a + b(旧b的值)print(n)改成函数:def fib(max):a,b = 0,1n = 0  # 斐波那契数while n < max:n = a + ba = b # 把b的旧值给到ab = n # 新的b = a + b(旧b的值)print(n)fib(100)
仔细观察,可以看出,fib函数实际上是定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意
的元素,这种逻辑其实非常类似generator也就是说,上面的函数和generator仅一步之遥。要把fib函数变成generator,只需要把print(b)改为
yield b就可以了def fib(max):a,b = 0,1n = 0  # 斐波那契数while n < max:n = a + ba = b # 把b的旧值给到ab = n # 新的b = a + b(旧b的值)#print(n)yield n # 程序走到这,就会暂停下来,返回n到函数外面,直到被next方法调用时唤醒
f = fib(100) # 注意这句调用时,函数并不会执行,只有下一次调用next时,函数才会真正执行
print(f)
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())而变成generator的函数,在每次调用next()的时候执行,遇到yield语句暂停并返回数据到函数外,再次被
next()调用时从上次返回的yield语句处继续执行。并发编程:虽然我们还没学并发编程,但我们肯定听过cpu 多少核多少核之类的,cpu的多核就是为了可以实现并行运算,让你同时边听歌、边聊qq、边刷知乎。单核的cpu同一时间只能干一个事,所以你用单核电脑同时做好几件事的话,就会变的很慢,因为cpu要在不同程序任务间来回切换通过yield, 我们可以实现单核下并发做多件事的效果:import timedef consumer(name):print("%s 准备吃包子啦!" %name)while True:baozi = yield  # yield可以接收到外部send传过来的数据并赋值给baoziprint("包子[%s]来了,被[%s]吃了!" %(baozi,name))c = consumer('A')c2 = consumer('B')c.__next__() # 执行一下next可以使上面的函数走到yield那句。 这样后面的send语法才能生效c2.__next__()print("----老子开始准备做包子啦!----")for i in range(10):time.sleep(1)print("做了2个包子!")c.send(i)  # send的作用=next, 同时还把数据传给了上面函数里的yieldc2.send(i)注意:调用send(x)给生成器传值时,必须确保生成器已经执行过一次next()调用, 这样会让程序走到yield位置等待外部第2次调用。

4.2 迭代器:

我们已经知道,可以直接作用于for循环的数据类型有以下几种:一类是集合数据类型,如list、tuple、dict、set、str等;一类是generator,包括生成器和带yield的generator function。这些可以直接作用于for循环的对象统称为(可迭代对象):Iterable,可迭代的意思就是可遍历、可循环。可以使用isinstance()判断一个对象是否是Iterable对象:
>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration
错误表示无法继续返回下一个值了。*可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。小结:1.凡是可作用于for循环的对象都是Iterable类型;2.凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;3.集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

第二章 常用模块:

1.什么是模块:

    为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少很多编程语言都采用这种组织代码的方式。在Python中,一个.py文件就可以称之为一个模块(Module)。模块的好处:1.最大的好处是大大提高了代码的可维护性,编写代码不必从零开始。2.使用模块还可以避免函数名和变量名冲突。每个模块有独立的命名空间,因此相同名字的函数和变量完全可以分别存在不同的模块中,所以,我们自己在编写模块时,不必考虑名字会与其他模块冲突模块的分类:模块分为三种:1.内置标准模块(又称标准库)执行help(‘modules’)查看所有python自带模块列表2.第三方开源模块,可通过pip install 模块名 联网安装3.自定义模块导入方式:import module_a  #导入from module import xxfrom module.xx.xx import xx as rename #导入后重命令from module.xx.xx import *  #导入一个模块下的所有方法,不建议使用module_a.xxx  #调用自定义模块:这个最简单, 创建一个.py文件,就可以称之为模块,就可以在另外一个程序里导入
查找路径:print(__file__)  # 打印当前脚本所在的路径,包含文件名print(os.path.abspath(__file__))  # 打印当前脚本的绝对路径

2. 第三方开源模块:

https://pypi.python.org/pypi是python的开源模块库,截止2019年4.30日 ,已经收录了175870个来自
全世界python开发者贡献的模块,几乎涵盖了你想用python做的任何事情。 事实上每个python开发者,只要注册
一个账号就可以往这个平台上传你自己的模块,这样全世界的开发者都可以容易的下载并使用你的模块。

1.模块下载命令:

    pip install -i http://pypi.douban.com/simple/ alex_sayhi --trusted-host pypi.douban.com-i 后面跟的是豆瓣源地址—trusted-host 得加上,是通过网站https安全验证用的

2.系统调用os模块:

    得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd()返回指定目录下的所有文件和目录名:os.listdir()函数用来删除一个文件:os.remove()删除多个目录:os.removedirs(r“c:\python”)检验给出的路径是否是一个文件:os.path.isfile()检验给出的路径是否是一个目录:os.path.isdir()判断是否是绝对路径:os.path.isabs()检验给出的路径是否真地存:os.path.exists()返回一个路径的目录名和文件名:os.path.split()e.g os.path.split('/home/swaroop/byte/code/poem.txt')结果:('/home/swaroop/byte/code', 'poem.txt')分离扩展名:os.path.splitext()       e.g  os.path.splitext('/usr/local/test.py')    结果:('/usr/local/test', '.py')获取路径名:os.path.dirname()获得绝对路径: os.path.abspath()获取文件名:os.path.basename()运行shell命令: os.system()读取操作系统环境变量HOME的值:os.getenv("HOME")返回操作系统所有的环境变量: os.environ设置系统环境变量,仅程序运行时有效:os.environ.setdefault('HOME','/home/alex')给出当前平台使用的行终止符:os.linesep    Windows使用'\r\n',Linux and MAC使用'\n'指示你正在使用的平台:os.name       对于Windows,它是'nt',而对于Linux/Unix用户,它是'posix'重命名:os.rename(old, new)创建多级目录:os.makedirs(r“c:\python\test”)创建单个目录:os.mkdir(“test”)获取文件属性:os.stat(file)修改文件权限与时间戳:os.chmod(file)获取文件大小:os.path.getsize(filename)结合目录名与文件名:os.path.join(dir,filename)改变工作目录到dirname: os.chdir(dirname)获取当前终端的大小: os.get_terminal_size()杀死进程: os.kill(10884,signal.SIGKILL)

3.系统调用sys模块:

    sys.argv           命令行参数List,第一个元素是程序本身路径sys.exit(n)        退出程序,正常退出时exit(0)sys.version        获取Python解释程序的版本信息sys.maxint         最大的Int值sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值sys.platform       返回操作系统平台名称sys.stdout.write('please:')  #标准输出 , 引出进度条的例子, 注,在py3上不行,可以用print代替val = sys.stdin.readline()[:-1] #标准输入sys.getrecursionlimit() #获取最大递归层数sys.setrecursionlimit(1200) #设置最大递归层数sys.getdefaultencoding()  #获取解释器默认编码sys.getfilesystemencoding  #获取内存数据存到文件里的默认编码

4.time & datetime模块:

    时间处理有关的模块就包括:time,datetime,calendar(很少用,不讲),下面分别来介绍。我们写程序时对时间的处理可以归为以下3种:时间的显示,在屏幕显示、记录日志等时间的转换,比如把字符串格式的日期转成Python中的日期类型时间的运算,计算两个日期间的差值等time模块:1.时间戳(timestamp), 表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。例子:1554864776.1619012.格式化的时间字符串,比如“2020-10-03 17:54”3.元组(struct_time)共九个元素。由于Python的time模块实现主要调用C库,所以各个平台可能有所不同,mac上:time.struct_time(tm_year=2020, tm_mon=4, tm_mday=10, tm_hour=2,tm_min=53, tm_sec=15, tm_wday=2, tm_yday=100, tm_isdst=0)索引(Index)    属性(Attribute)    值(Values)0     tm_year(年)                 比如20111     tm_mon(月)                  1 - 122     tm_mday(日)                 1 - 313     tm_hour(时)                 0 - 234     tm_min(分)                  0 - 595     tm_sec(秒)                  0 - 616     tm_wday(weekday)            0 - 6(0表示周日)7     tm_yday(一年中的第几天)       1 - 3668     tm_isdst(是否是夏令时)        默认为-1UTC时间:UTC(Coordinated Universal Time,世界协调时)亦即格林威治天文时间,世界标准时间。在中国为UTC+8,又称东8区。DST(Daylight Saving Time)即夏令时。time模块用法:time.localtime([secs]):将一个时间戳转换为当前时区的struct_time。若secs参数未提供,则以当前时间为准。time.gmtime([secs]):和localtime()方法类似,gmtime()方法是将一个时间戳转换为UTC时区(0时区)的struct_time。time.time():返回当前时间的时间戳。time.mktime(t):将一个struct_time转化为时间戳。time.sleep(secs):线程推迟指定的时间运行,单位为秒。time.asctime([t]):把一个表示时间的元组或者struct_time表示为这种形式:’Sun Oct 1 12:04:38 2019’。如果没有参数,将会将time.localtime()作为参数传入。time.ctime([secs]):把一个时间戳(按秒计算的浮点数)转化为time.asctime()的形式。如果参数未给或者为None的时候,将会默认time.time()为参数。它的作用相当于time.asctime(time.localtime(secs))。time.strftime(format[, t]):把一个代表时间的元组或者struct_time(如由time.localtime()和time.gmtime()返回)转化为格式化的时间字符串。如果t未指定,将传入time.localtime()。举例:time.strftime(“%Y-%m-%d %X”, time.localtime()) #输出’2017-10-01 12:14:23’time.strptime(string[, format]):把一个格式化时间字符串转化为struct_time。实际上它和strftime()是逆操作。举例:time.strptime(‘2017-10-3 17:54’,”%Y-%m-%d %H:%M”) #输出 time.struct_time(tm_year=2017, tm_mon=10, tm_mday=3, tm_hour=17, tm_min=54, tm_sec=0, tm_wday=1, tm_yday=276, tm_isdst=-1)字符串转时间格式对应表:%a 语言环境的缩写工作日名称.%A 区域设置的完整工作日名称.%b Locale缩写的月份名称.%B    地区的完整月份名称.%c    地区的适当日期和时间表示.%d 以十进制数表示的月份的一天[01,31].%H 小时(24小时时钟),十进制数[00,23].%I    小时(12小时时钟),作为十进制数[01,12].%j  一年中的一天(十进制数)[001,366].%m 月(十进制数字[01,12]).%M  分钟(十进制数)[00,59].%p  Locale相当于AM或PM。(1)%S    以十进制数[00,61]的第二名。(2)%U  一年的周数(星期日是一周的第一天),以十进制数[00,53]表示。新年第一个星期日之前的所有日子都被认为是在第0周.   (3)%w   以小数形式表示的工作日[0(星期日),6]。%W 一年的周数(星期一是一周的第一天),以十进制数[00,53]表示。新年第一个星期一之前的所有日子都被认为是在第0周.   (3)%x   地区的适当日期表示.%X    区域设置的适当时间表示.%y  没有世纪的年份作为十进制数[00,99].%Y 以世纪作为十进制数的年份。%z 时区偏移量,表示与UTC/GMT的正或负时差,形式为+HHMM或-HHMM,其中H表示十进制小时数,M表示十进制分钟数[-23:59,+23:59]%Z   时区名称(如果不存在时区,则不使用字符)。datetime模块:相比于time模块,datetime模块的接口则更直观、更容易调用。datetime模块定义了下面这几个类:datetime.date:表示日期的类。常用的属性有year, month, day;datetime.time:表示时间的类。常用的属性有hour, minute, second, microsecond;datetime.datetime:表示日期时间。datetime.timedelta:表示时间间隔,即两个时间点之间的长度。datetime.tzinfo:与时区有关的相关信息。(这里不详细充分讨论该类,感兴趣的童鞋可以参考python手册)我们需要记住的方法仅以下几个:1.d=datetime.datetime.now() 返回当前的datetime日期类型d.timestamp(),d.today(), d.year,d.timetuple()等方法可以调用1.datetime.date.fromtimestamp(322222) 把一个时间戳转为datetime日期类型2.时间运算>>> datetime.datetime.now()datetime.datetime(2017, 10, 1, 12, 53, 11, 821218)>>> datetime.datetime.now() + datetime.timedelta(4) #当前时间 +4天datetime.datetime(2017, 10, 5, 12, 53, 35, 276589)>>> datetime.datetime.now() + datetime.timedelta(hours=4) #当前时间+4小时datetime.datetime(2017, 10, 1, 16, 53, 42, 876275)4.时间替换>>> d.replace(year=2999,month=11,day=30)datetime.date(2999, 11, 30)

5.random随机数模块:

程序中有很多地方需要用到随机字符,比如登录网站的随机验证码,通过random模块可以很容易生成随机字符串
>>> random.randrange(1,10) #返回1-10之间的一个随机数,不包括10
>>> random.randint(1,10) #返回1-10之间的一个随机数,包括10
>>> random.randrange(0, 100, 2) #随机选取0到100间的偶数
>>> random.random()  #返回一个随机浮点数
>>> random.choice('abce3#$@1') #返回一个给定数据集合中的随机字符
'#'
>>> random.sample('abcdefghij',3)  #从多个字符中选取特定数量的字符
['a', 'd', 'b']#洗牌
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> random.shuffle(a)
>>> a
[3, 0, 7, 2, 1, 6, 5, 8, 9, 4]import stringprint(string.ascii_uppercase)
print(string.ascii_lowercase)
print(string.digits)#生成随机验证码字符串
>>> import string
>>> ''.join(random.sample(string.ascii_lowercase + string.digits, 6))
'4fvda1'

6.序列化pickle&json模块:

1.pickle:pickle用于python特有的类型 和 python的数据类型间进行转换pickle模块提供了四个功能:dumps、dump、loads、loadimport pickledata = {'k1':123,'k2':'Hello'}# pickle.dumps 将数据通过特殊的形式转换位只有python语言认识的字符串p_str = pickle.dumps(data)  # 注意dumps会把数据变成bytes格式print(p_str)# pickle.dump 将数据通过特殊的形式转换位只有python语言认识的字符串,并写入文件with open('result.pk',"wb") as fp:pickle.dump(data,fp)# pickle.load  从文件里加载f = open("result.pk","rb")d = pickle.load(f)print(d)2.json:json,用于字符串 和 python数据类型间进行转换Json模块也提供了四个功能:dumps、dump、loads、load,用法跟pickle一致import json# json.dumps 将数据通过特殊的形式转换位所有程序语言都认识的字符串j_str = json.dumps(data) # 注意json dumps生成的是字符串,不是bytesprint(j_str)#dump入文件with open('result.json','w') as fp:json.dump(data,fp)#从文件里loadwith open("result.json") as f:d = json.load(f)print(d)3.json VS pickle:json:优点:跨语言(不同语言间的数据传递可用json交接)、体积小缺点:只能支持int\str\list\tuple\dictpickle:优点:专为python设计,支持python所有的数据类型缺点:只能在python中使用,存储数据占空间大

7.hashlib加密:

HASH:Hash,一般翻译做“散列”,也有直接音译为”哈希”的,就是把任意长度的输入(又叫做预映射,pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。HASH主要用于信息安全领域中加密算法,他把一些不同长度的信息转化成杂乱的128位的编码里,叫做HASH值.也可以说,hash就是找到一种数据内容和数据存放地址之间的映射关系MD5:MD5讯息摘要演算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码杂凑函数,可以产生出一个128位的散列值(hash value),用于确保信息传输完整一致。MD5的前身有MD2、MD3和MD4MD5功能:输入任意长度的信息,经过处理,输出为128位的信息(数字指纹);不同的输入得到的不同的结果(唯一性)MD5算法的特点:压缩性:任意长度的数据,算出的MD5值的长度都是固定的容易计算:从原数据计算出MD5值很容易抗修改性:对原数据进行任何改动,修改一个字节生成的MD5值区别也会很大强抗碰撞:已知原数据和MD5,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。MD5算法是否可逆?MD5不可逆的原因是其是一种散列函数,使用的是hash算法,在计算过程中原文的部分信息是丢失了的MD5用途:1.防止被篡改2.比如发送一个电子文档,发送前,我先得到MD5的输出结果a。然后在对方收到电子文档后,对方也得到一个MD5的输出结果b。如果a与b一样就代表中途未被篡改。3.比如我提供文件下载,为了防止不法分子在安装程序中添加木马,我可以在网站上公布由安装文件得到的MD5输出结果。4.SVN在检测文件是否在CheckOut后被修改过,也是用到了MD5.5.现在很多网站在数据库存储用户的密码的时候都是存储用户密码的MD5值。这样就算不法分子得到数据库的用户密码的MD5值,也无法知道用户的密码6.这需要一个第三方认证机构。例如A写了一个文件,认证机构对此文件用MD5算法产生摘要信息并做好记录。SHA-1:安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要。当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。SHA是美国国家安全局设计的,由美国国家标准和技术研究院发布的一系列密码散列函数。由于MD5和SHA-1于2005年被山东大学的教授王小云破解了,科学家们又推出了SHA224, SHA256, SHA384, SHA512,当然位数越长,破解难度越大,但同时生成加密的消息摘要所耗时间也更长。目前最流行的是加密算法是SHA-256 .MD5与SHA-1的比较:由于MD5与SHA-1均是从MD4发展而来,它们的结构和强度等特性有很多相似之处,SHA-1与MD5的最大区别在于其摘要比MD5摘要长32 比特。对于强行攻击,产生任何一个报文使之摘要等于给定报文摘要的难度:MD5是2128数量级的操作,SHA-1是2160数量级的操作。产生具有相同摘要的两个报文的难度:MD5是264是数量级的操作,SHA-1 是280数量级的操作。因而,SHA-1对强行攻击的强度更大。但由于SHA-1的循环步骤比MD5多80:64且要处理的缓存大160比特:128比特,SHA-1的运行速度比MD5慢。Python的 提供的相关模块:用于加密相关的操作,3.x里用hashlib代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5算法import hashlib# md5m = hashlib.md5()m.update(b"Hello")m.update(b"It's me")print(m.digest())  # 返回2进制格式的hash值m.update(b"It's been a long time since last time we ...")print(m.hexdigest()) # 返回16进制格式的hash值# sha1s1 = hashlib.sha1()s1.update("小猿圈".encode("utf-8"))s1.hexdigest()# sha256s256 = hashlib.sha256()s256.update("小猿圈".encode("utf-8"))s256.hexdigest()# sha512s512 = hashlib.sha256()s512.update("小猿圈".encode("utf-8"))s512.hexdigest()

8.文件copy模块shutil:

高级的 文件、文件夹、压缩包 处理模块1.将文件内容拷贝到另一个文件中import shutilshutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))2.拷贝文件shutil.copyfile('f1.log', 'f2.log') #目标文件无需存在3.仅拷贝权限。内容、组、用户均不变shutil.copymode('f1.log', 'f2.log') #目标文件必须存在4.仅拷贝状态的信息,包括:mode bits, atime, mtime, flagsshutil.copystat('f1.log', 'f2.log') #目标文件必须存在5.拷贝文件和权限import shutilshutil.copy('f1.log', 'f2.log')6.拷贝文件和状态信息import shutilshutil.copy2('f1.log', 'f2.log')7.递归的去拷贝文件夹import shutilshutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) #目标目录不能存在,注意对folder2目录父级目录要有可写权限,ignore的意思是排除8.递归的去删除文件import shutilshutil.rmtree('folder1')9.递归的去移动文件,它类似mv命令,其实就是重命名。import shutilshutil.move('folder1', 'folder3')

9.创建压缩包并返回文件路径,例如:zip、tar

可选参数如下:base_name:压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,如 data\_bak =&gt;保存至当前路径如:/tmp/data\_bak =&gt;保存至/tmp/format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”root_dir: 要压缩的文件夹路径(默认当前目录)owner: 用户,默认当前用户group: 组,默认当前组logger: 用于记录日志,通常是logging.Logger对象示例:#将 /data 下的文件打包放置当前程序目录import shutilret = shutil.make_archive("data_bak", 'gztar', root_dir='/data')#将 /data下的文件打包放置 /tmp/目录import shutilret = shutil.make_archive("/tmp/data_bak", 'gztar', root_dir='/data')1.zipfile压缩&解压缩import zipfile# 压缩z = zipfile.ZipFile('laxi.zip', 'w')z.write('a.log')z.write('data.data')z.close()# 解压z = zipfile.ZipFile('laxi.zip', 'r')z.extractall(path='.')z.close()2.tarfile压缩&解压缩import tarfile# 压缩>>> t=tarfile.open('/tmp/egon.tar','w')>>> t.add('/test1/a.py',arcname='a.bak')>>> t.add('/test1/b.py',arcname='b.bak')>>> t.close()# 解压>>> t=tarfile.open('/tmp/egon.tar','r')>>> t.extractall('/egon')>>> t.close()

10.正则表达式 & re模块:

1.re模块:正则表达式就是字符串的匹配规则,在多数编程语言里都有相应的支持,python里对应的模块是re2.常用的表达式规则:'.'     默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行'^'     匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)'$'     匹配字符结尾, 若指定flags MULTILINE ,re.search('foo.$','foo1\nfoo2\n',re.MULTILINE).group() 会匹配到foo1'*'     匹配*号前的字符0次或多次, re.search('a*','aaaabac')  结果'aaaa''+'     匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb']'?'     匹配前一个字符1次或0次 ,re.search('b?','alex').group() 匹配b 0次'{m}'   匹配前一个字符m次 ,re.search('b{3}','alexbbbs').group()  匹配到'bbb''{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb']'|'     匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC''(...)' 分组匹配, re.search("(abc){2}a(123|45)", "abcabca456c").group() 结果为'abcabca45''\A'    只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的,相当于re.match('abc',"alexabc") 或^'\Z'    匹配字符结尾,同$'\d'    匹配数字0-9'\D'    匹配非数字'\w'    匹配[A-Za-z0-9]'\W'    匹配非[A-Za-z0-9]'s'     匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t''(?P...)' 分组匹配 re.search("(?P[0-9]{4})(?P[0-9]{2})(?P[0-9]{4}3.re的匹配语法有以下几种:re.match 从头开始匹配re.search 匹配包含re.findall 把所有匹配到的字符放到以列表中的元素返回re.split 以匹配到的字符当做列表分隔符re.sub 匹配字符并替换re.fullmatch 全部匹配4.re.compile(pattern, flags=0):序列:prog = re.compile(pattern)result = prog.match(string)相当于:result = re.match(pattern, string)但是,当表达式在单个程序中被多次使用时,使用re.compile()并保存生成的正则表达式对象以供重用会更有效5.re.match(pattern, string, flags=0):从起始位置开始根据模型去字符串中匹配指定内容,匹配单个pattern 正则表达式string 要匹配的字符串flags 标志位,用于控制正则表达式的匹配方式示例:import reobj = re.match('\d+', '123uuasf') #如果能匹配到就返回一个可调用的对象,否则返回Noneif obj:print obj.group()6.Flags标志符:re.I(re.IGNORECASE): 忽略大小写(括号内是完整写法,下同)re.M(MULTILINE): 多行模式,改变’^’和’$’的行为re.S(DOTALL): 改变’.’的行为,make the ‘.’ special character match any character at all, including a newline; without this flag, ‘.’ will match anything except a newline.re.X(re.VERBOSE) 可以给你的表达式写注释,使其更可读,下面这2个意思一样示例:a = re.compile(r"""\d + # the integral part\. # the decimal point\d * # some fractional digits""",re.X)b = re.compile(r"\d+\.\d*")7.re.search(pattern, string, flags=0)根据模型去字符串中匹配指定内容,匹配单个import reobj = re.search('\d+', 'u123uu888asf')if obj:print obj.group()8.re.findall(pattern, string, flags=0)match and search均用于匹配单值,即:只能匹配字符串中的一个,如果想要匹配到字符串中所有符合条件的元素,则需要使用 findall。import reobj = re.findall('\d+', 'fa123uu888asf')print obj9.re.sub(pattern, repl, string, count=0, flags=0)用于替换匹配的字符串,比str.replace功能更加强大>>>re.sub('[a-z]+','sb','武配齐是abc123',)>>> re.sub('\d+','|', 'alex22wupeiqi33oldboy55',count=2)'alex|wupeiqi|oldboy55'10.re.split(pattern, string, maxsplit=0, flags=0)用匹配到的值做为分割点,把值分割成列表>>>s='9-2*5/3+7/3*99/4*2998+10*568/14'>>>re.split('[\*\-\/\+]',s)['9', '2', '5', '3', '7', '3', '99', '4', '2998', '10', '568', '14']>>> re.split('[\*\-\/\+]',s,3)['9', '2', '5', '3+7/3*99/4*2998+10*568/14']11.re.fullmatch(pattern, string, flags=0)整个字符串匹配成功就返回re object, 否则返回Nonere.fullmatch('\w+@\w+\.(com|cn|edu)',"alex@oldboyedu.cn")

11.软件开发目录设计规范:

为什么要设计好目录结构?1.可读性高不熟悉这个项目的代码的人,一眼就能看懂目录结构,知道程序启动脚本是哪个,测试目录在哪儿,配置文件在哪儿等等。从而非常快速的了解这个项目。2.可维护性高定义好组织规则后,维护者就能很明确地知道,新增的哪个文件和代码应该放在什么目录之下。这个好处是,随着时间的推移,代码/配置的规模增加,项目结构不会混乱,仍然能够组织良好。目录组织方式:假设你的项目名为foo, 我比较建议的最方便快捷目录结构这样就足够了:Foo/|-- bin/|   |-- foo||-- foo/|   |-- tests/|   |   |-- __init__.py|   |   |-- test_main.py|   ||   |-- __init__.py|   |-- main.py||-- docs/|   |-- conf.py|   |-- abc.rst||-- setup.py|-- requirements.txt|-- README简要解释一下:bin/: 存放项目的一些可执行文件,当然你可以起名script/之类的也行。foo/: 存放项目的所有源代码。(1) 源代码中的所有模块、包都应该放在此目录。不要置于顶层目录。(2) 其子目录tests/存放单元测试代码; (3) 程序的入口最好命名为main.py。docs/: 存放一些文档。setup.py: 安装、部署、打包的脚本。requirements.txt: 存放软件依赖的外部Python包列表。README: 项目说明文件。关于README的内容:这个我觉得是每个项目都应该有的一个文件,目的是能简要描述该项目的信息,让读者快速了解这个项目。它需要说明以下几个事项:软件定位,软件的基本功能。运行代码的方法: 安装环境、启动命令等。简要的使用说明。代码目录结构说明,更详细点可以说明软件的基本原理。常见问题说明。关于requirements.txt和setup.py
setup.py一般来说,用setup.py来管理代码的打包、安装、部署问题。业界标准的写法是用Python流行的打包工具setuptools来管理这些事情。这种方式普遍应用于开源项目中。不过这里的核心思想不是用标准化的工具来解决这些问题,而是说,一个项目一定要有一个安装部署工具,能快速便捷的在一台新机器上将环境装好、代码部署好和将程序运行起来。requirements.txt这个文件存在的目的是:1.方便开发者维护软件的包依赖。将开发过程中新增的包添加进这个列表中,避免在setup.py安装依赖时漏掉软件包。2.方便读者明确项目使用了哪些Python包。

12.包&跨包模块代码调用:

包(Package):当你的模块文件越来越多,就需要对模块文件进行划分,比如把负责跟数据库交互的都放一个文件夹,把与页面交互相关的放一个文件夹my_proj/├── apeland_web  #代码目录│   ├── __init__.py│   ├── admin.py│   ├── apps.py│   ├── models.py│   ├── tests.py│   └── views.py├── manage.py└── my_proj    #配置文件目录├── __init__.py├── settings.py├── urls.py└── wsgi.py1.像上面这样,一个文件夹管理多个模块文件,这个文件夹就被称为包2.一个包就是一个文件夹,但该文件夹下必须存在init.py 文件, 该文件的内容可以为空,int.py用于标识当前文件夹是一个包。3.这个init.py的文件主要是用来对包进行一些初始化的,当当前这个package被别的程序调用时,init.py文件会先执行,一般为空, 一些你希望只要package被调用就立刻执行的代码可以放在init.py里,一会后面会演示。跨模块导入:目录结构如下my_proj├── apeland_web│   ├── __init__.py│   ├── admin.py│   ├── apps.py│   ├── models.py│   ├── tests.py│   └── views.py├── manage.py└── my_proj├── settings.py├── urls.py└── wsgi.py根据上面的结构,如何实现在apelandweb/views.py里导入myproj/settings.py模块?直接导入的话,会报错,说找到不模块方法1:添加环境变量import sys ,osBASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #__file__的是打印当前被执行的模块.py文件相对路径,注意是相对路径print(BASE_DIR) # 输出是/Users/alex/PycharmProjects/apeland_py_learn/day4_常用模块/my_projsys.path.append(BASE_DIR)from  my_proj import settingsprint(settings.DATABASES)方法2:官方推荐在项目里创建个入口程序,整个程序调用的开始应该是从入口程序发起,这个入口程序一般放在项目的顶级目录这样做的好处是,项目中的二级目录 apeland_web/views.py中再调用他表亲my_proj/settings.py时就不用再添加环境变量了。原因是由于manage.py在顶层,manage.py启动时项目的环境变量路径就会自动变成….xxx/my_proj/这一级别

Python函数编程相关推荐

  1. python函数编程-偏函数partial function

    python函数编程-偏函数partial function 一般的,通过设定函数参数的默认值,可以减低函数调用的难度.比如:int()函数可以把字符串转换成整数: >>> int( ...

  2. Python函数编程——函数简介

    Python函数编程--函数简介 引子 现在老板让你写一个监控程序,24小时全年无休的监控你们公司网站服务器的系统状况,当cpu\memory\disk等指标的使用量超过阀值时即发邮件报警,你掏空了所 ...

  3. python函数的特性_深入Python函数编程的一些特性

    绑定 细心的读者可能记得我在 第 1 部分的函数技术中指出的限制.特别在 Python 中不能避免表示函数表达式的名称的重新绑定.在 FP 中,名称通常被理解为较长表达式的缩写,但这一说法暗示着&qu ...

  4. python函数编程序_可爱的 Python: Python 中的函数编程(4)

    在除去完美的.有意义的语句不用而代之以晦涩的.嵌套的表达式的工作后,一个很自然的问题是:"为什么?!"我对 FP 的所有描述都是使用 Python 做到的.但最重要的特性 -- 可 ...

  5. python函数编程求三个数的最小公倍数_Python求三个数的最小公倍数

    题目 求三个数的最小公倍数 思路 首先求两个数的最小公倍数,再求这个最小公倍数与第三个数的最小公倍数就是最终结果 有两种方案求两个数的最小公倍数 1. 分解质因数,也是短除法(在程序上差别不大) 循环 ...

  6. python函数编程实战_(转)函数式编程实战教程(Python版)

    许多函数式文章讲述的是组合,流水线和高阶函数这样的抽象函数式技术.本文不同,它展示了人们每天编写的命令式,非函数式代码示例,以及将这些示例转换为函数式风格. 文章的第一部分将一些短小的数据转换循环重写 ...

  7. python函数编程实战_别找了,这是 Pandas 最详细教程了

    Python 是开源的,它很棒,但是也无法避免开源的一些固有问题:很多包都在做(或者在尝试做)同样的事情.如果你是 Python 新手,那么你很难知道某个特定任务的最佳包是哪个,你需要有经验的人告诉你 ...

  8. python 函数编程

    函数的定义:(function) 代码块. 就是将我们要执行的代码进行结构的整合,形成可被调用的代码块 函数是可以重复调用的代码块 函数比较代码复制 1. 减少冗余代码 2. 代码结构清晰 3. 有助 ...

  9. python函数编程实例_Python函数式编程实例详解

    本文实例讲述了Python函数式编程.分享给大家供大家参考,具体如下: 函数式编程就是一种抽象程度很高的编程范式,从计算机硬件->汇编语言->C语言->Python抽象程度越高.越贴 ...

最新文章

  1. 网络推广公司网站该如何针对主页的优化工作?
  2. 【数理逻辑】谓词逻辑 ( 个体词 | 个体域 | 谓词 | 全称量词 | 存在量词 | 谓词公式 | 习题 )
  3. 标准配置的UBUNTU 11.10 RUBY VMWARE 镜像,手工MOD(ZSH_RVM_RAILS_VIM)
  4. 学生用计算机说明方法,15.文中多处运用了作比较的说明方法.请任选一例.说说运用这种方法的作用. 例子: 作用:...
  5. 电力电子、电机控制系统的建模和仿真_清华团队研发,首款国产电力电子仿真软件来啦~已捐赠哈工大、海工大、清华使用!...
  6. Java中的Enum的使用与分析
  7. tar.gz 文件解压 (安装 netbean 时会用到)
  8. Linux环境下Protobuf完整安装和使用教程
  9. 实时统计分析技术浅谈
  10. Tesseract-OCR识别中文与训练字库实例
  11. 【linux】linux下修改鼠标指针
  12. 2021年PTCMS4.3最新采集规则13条
  13. 员工管理系统————员工添加模块
  14. DWG文件怎么转成PDF格式?介绍两种方式
  15. c#使用wpd读取便携式设备信息二
  16. Docker 底层技术推导
  17. JavaScript伪数组和数组
  18. 沁恒微电子CH9120是一款网络串口透传芯片
  19. 基于PaddleNLP的真假新闻分类(二)Skep模型
  20. 怀旧服 服务器 维护,魔兽世界怀旧服人太多服务器爆了 紧急维护再次新增服务器...

热门文章

  1. 十一、总结一下今天在SpringAOP中遇到的一个坑,事务控制一直失败,自己感觉代码没错的感觉,往底层看,很明了了
  2. python matplotlib 显示中文的问题
  3. 转如何管理好开源软件社区:开源项目管理方法
  4. ubuntu 查看opencv以及opencv4版本
  5. 7代服务器cpu型号,七代酷睿都有哪些型号?_笔记本新闻-中关村在线
  6. mysql sniffer 源码_MySQL 抓包工具 - MySQL Sniffer 使用小结 (含带general_log日志)
  7. 换个角度看“量子技术”,它离我们可能不再遥远
  8. 操作系统------资源分配图化简
  9. 搭载在电源插座上的IoT革命
  10. 信息传输速率与传信率_波特率和数据传输速率的关系