深入理解Python中的模块、包、递归和正则表达式

来源:互联网 发布:苏州聚合数据怎么样 编辑:程序博客网 时间:2024/05/21 14:44

博客核心内容:


  1. 匿名函数的用法介绍
  2. 递归以及二分法的应用
  3. Python中的模块
  4. Python中内置变量__main__的使用
  5. Python中模块的搜索路径
  6. Python中的包
  7. 正则表达式

1、 匿名函数的用法介绍

匿名函数的定义:匿名函数就是不需要显式的指定函数,此时我们关注的是执行体。
示例程序:

fun = lambda x,y:x+yprint(fun(10,20))

运行结果:

30
2、递归以及二分法的介绍

递归的含义:一个函数直接或者间接的调用自己。
递归特性:
1. 必须有一个明确的结束条件
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
示例程序:二分法

#!/usr/bin/python# -*- coding:utf-8 -*-data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]def binary_search(dataset, find_num):    print(dataset)    if len(dataset) > 1:        mid = int(len(dataset) / 2)        if dataset[mid] == find_num:  # find it            print("找到数字", dataset[mid])        elif dataset[mid] > find_num:  # 找的数在mid左面            print("\033[31;1m找的数在mid[%s]左面\033[0m" % dataset[mid])            return binary_search(dataset[0:mid], find_num)        else:  # 找的数在mid右面            print("\033[32;1m找的数在mid[%s]右面\033[0m" % dataset[mid])            return binary_search(dataset[mid + 1:], find_num)    else:        if dataset[0] == find_num:  # find it            print("找到数字啦", dataset[0])        else:            print("没的分了,要找的数字[%s]不在列表里" % find_num)binary_search(data, 66)

运行结果:

[1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]找的数在mid[18]右面[20, 21, 22, 23, 30, 32, 33, 35]找的数在mid[30]右面[32, 33, 35]找的数在mid[33]右面[35]没的分了,要找的数字[66]不在列表里Process finished with exit code 0
3、Python中的模块

模块的概念:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀。
使用模块的原因:如果你退出python解释器然后重新进入,那么你之前定义的函数或者变量都将丢失,因此我们通常将程序写到文件中以便永久保存下来,需要时就通过python test.py方式去执行,此时test.py被称为脚本script。
模块的相关概念:
模块的概念:一个py文件就是一个模块;包也是一种形式的模块。文件名字 = 模块的名字 + .py的后缀。
文件共有两种使用方式: 1.直接将文件当做一个脚本来运行。2.被当做一个模块导入进来。
模块使用的三种方式:
1.import spam
2.from spam import money
3.from spam import * (将模块中的变量都导入,并且不用加前缀,少用)
注意:可以使用all来控制被导入的模块中*代表的是什么意思。
import spam导入模块做的事情:
1.产生新的名称空间。
3.以新建的名称空间为全局名称空间,执行文件中的代码.(指针变量p所指向的那块内存空间的代码)
2.拿到一个模块的名字(地址),指向spam.py产生的名称空间。

from spam import money导入模块做的事情:(从spam空间中拿到money这个变量)
1.产生新的名称空间。
3.以新建的名称空间为全局名称空间,执行文件中的代码.(指针变量p所指向的那块内存空间的代码)
2.直接拿到的就是spam.py产生的名称空间中的名字。
4.注意:这种方式并没有获取到spam,仅仅获取的是money,优点是不用加前缀了,缺点是容易和当前文件的名称空间
产生冲突。
相同点:两种方式在执行的时候都是以源文件为准。
不同点:导入的方式不同。
注意:1.一定要区分出当前文件的名称空间和spam文件所对应的名称空间,这两个名称空间是不同的,当前名称空间根本就不能改动源名称空间所对应变量的数值。2.无论是函数名字、还是模块名字、或者变量的名字,都具有一个绑定的过程。
import spam as x:可以给一个模块通过as起一个别名。
示例程序1:

#!/usr/bin/python# -*- coding:utf-8 -*-import spam   #将执行spam模块中的代码money = 100print("spam空间中money变量的数值是:%s"%spam.money) #获取spam空间的money变量print("spam空间中read1函数的内存地址是:%s"%spam.read1)spam.read1()  #执行spam空间对应的read1()函数def read1():    print("我是添乱的!")spam.read2()money = 10spam.change()  #此时修改的还是spam.py名称空间中的money变量print("money is %s"%money)import spam as xprint(x.money)

运行结果:

from the spam.pyspam空间中money变量的数值是:1000spam空间中read1函数的内存地址是:<function read1 at 0x000000000261CAE8>spam->read1->1000spam->read2->1000spam->read1->1000money is 100Process finished with exit code 0

示例程序2:

#!/usr/bin/python# -*- coding:utf-8 -*-from spam import money,read1,read2,changeprint("spam空间中money变量的数值是:%s"%money)money = 10  #此时的money对应的是当前空间中的moneyprint("此时变量money的数值是:%s"%money)import spamprint("spam空间中money变量对应的数值是:%s"%spam.money)print("%s%s%s"%(read1,read2,change)) #获取三个指针变量的数值def read1():    print("========>我是来捣乱的!")read2()import timemoney = 20print(money)from spam import read1read1()  #对应的是spam的命名空间def read1():    print("我是来捣乱的!")read1()  #对应的是当前文件的名称空间from spam import read1read1()  #对应的是spam的命名空间

运行结果:

from the spam.pyspam空间中money变量的数值是:1000此时变量money的数值是:10spam空间中money变量对应的数值是:1000<function read1 at 0x000000000263CAE8><function read2 at 0x000000000263C950><function change at 0x000000000263CB70>spam->read2->1000spam->read1->100020spam->read1->1000我是来捣乱的!spam->read1->1000Process finished with exit code 0

示例程序3:

#!/usr/bin/python# -*- coding:utf-8 -*-print("from the spam.py")__all__ = ["money"]  #限制对外开发的变量名字money = 1000def read1():    print("spam->read1->%s"%money)def read2():    print("spam->read2->%s"%money)    read1()def change():    #在这里面修改了全局的变量    global money    money = 0
4、Python中的内置函数__main__的使用

这里写图片描述
示例程序:
1、spam.py文件执行的时候:

#!/usr/bin/python# -*- coding:utf-8 -*-money = 1000def read1():    print("spam->read1->%s"%money)def read2():    print("spam->read2->%s"%money)    read1()def change():    #在这里面修改了全局的变量    global money    money = 0#spam.py当做脚本来执行的时候,__name__这个内置的变量等于__main__print("__name__的数值是:%s"%__name__)print(type(__name__))if __name__ == "__main__":    print("spam.py文件正在被当做脚本来执行")    change()    print(money)else:    print("spam.py文件正在被当做模块被导入")

运行结果:

__name__的数值是:__main__<class 'str'>spam.py文件正在被当做脚本来执行0Process finished with exit code 0

2、Test.py文件执行的时候:

#!/usr/bin/python# -*- coding:utf-8 -*-import spam

运行结果:

__name__的数值是:spam<class 'str'>spam.py文件正在被当做模块被导入Process finished with exit code 0
5、Python中模块的搜索路径

模块的搜索路径:1、优先在内存当中去寻找这个模块。
2、内置的模块
3、sys.path当中去寻找相应的模块:先在当前路径(以当前执行的文件路径为基准)下寻找,如果当前路径没有该模块,则依次向后寻找。
注意:sys.path当中,输出的第一个路径就是当前文件的路径,其余路径是对应环境变量的一些路径。
问题:如果某个模块在sys.path当中找不到,则可以将该模块对应的path加载到sys.path当中即可,如何加载呢?
1、代码的方式:
sys.path.append(r”D:\Python Work Location\Python 0507\dir1”)
2、手动放在sys.path当中的任何一个路径下即可。
问题:当我们import spam之后,spam点后并不会弹出相应的东西.
原因:PyCharm识别不了spam模块所在的路径,不在环境变量当中。
解决方法:点击—>mark directory as –> …….
代码示例1:我们可以将指定的模块放到sys.path当中,这样我们就可以在当前执行文件的路径之外去获取别的模块。
这里写图片描述

#!/usr/bin/python# -*- coding:utf-8 -*-import sys#将spam.py这个文件所在的路径加载到当前执行的文件的sys.path当中sys.path.append("D:\Python Work Location\Python 0507\dir1")import spamprint(spam.money)

运行结果:

from the spam1000Process finished with exit code 0
6、Python中的包

这里写图片描述
在Python当中没有.* ,只有from ….import *
.相当于./,..相当于../
核心知识点:(包下面有很多模块,模块下面有很多方法)
模块:通过模块可以从文件级别去组织我们的代码。
包:实际上也是一种形式的模块。
1. 无论是import形式还是from…import形式,凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高警觉:这是关于包才有的导入语法
import A.B.C.D 其中.的左边都必须是一个包,D本身可以是包,也可以是一个文件。
import glance.api.policy.get是错误的,因为policy本质上就不是一个包。
2. 包是目录级的(文件夹级),文件夹是用来组织py文件,(包的本质就是一个包含__init__.py文件的文件夹)。
从文件夹的级别可以很好的将文件的功能给区分出来。
3. import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件__init__.py并进行执行。即执行import glance 实际上是在执行 import glance._init_.py.下面的内容。
import glance.成员 = import glance._init_.py.成员

#!/usr/bin/python# -*- coding:utf-8 -*-import glance#glance.x 实际上是在执行glance._init_.py.xprint(glance.x)#glance.y 实际上是在执行glance._init_.py.yprint(glance.y)

import glance.api.policy
glance.api.policy.get() 发生的事情:
1.执行glance包下的_init_.py
2.执行api包下的_init_.py
3.执行policy模块下的get()函数
示例3:一切path的标准都以当前执行的文件为准。
错误示例:glance的_init_.py文件中写import api。
方法: import glance.api
注意:from glance import api.version这种写法是错误的,语法规定:from import后面的import不能出现.这种引用方式。
from glance.api import policy,version :从glance.api这个包中导入两个文件。
示例程序1:_ini_.py中的内容:
这里写图片描述

#!/usr/bin/python# -*- coding:utf-8 -*-from glance.api.policy  import getfrom glance.cmd.manage  import mainfrom glance.db.models  import register_modelsdef fun1():    print("spark")def fun2():    print("Hadoop")

随后我们去执行测试文件:test.py

#!/usr/bin/python# -*- coding:utf-8 -*-import glance#在_init_.py做文章导致的效果glance.register_models("python")glance.main()glance.get()

运行结果:

from apifrom models.py:  pythonfrom manage.pyfrom policy.pyProcess finished with exit code 0
7、正则表达式介绍

自从毕业之后就一直接触正则表达式,感觉这个地方是非常重要的一个知识点。
正则表达式的概念:正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法。或者说:正则就是用来描述一类事物的规则。(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。
简单的说:所谓正则表达式就是从字符串里面提取我想要的内容
正则表达式中的常用匹配规则:


这里写图片描述
这里写图片描述


示例程序:

#!/usr/bin/python# -*- coding:utf-8 -*-import reif __name__ == '__main__':    value1 = "as213df_*|"    print(re.findall("\w",value1))    print(re.findall(r"\W",value1))    value2 = "a_b a3b aEb a*b"    print(re.findall("a\wb","%s"%value2))    value3 = "a b\nc\td"    print(re.findall("\s","%s"%value3))    print(re.findall("\S", "%s" % value3))    value4 = "a123bcdef"    print(re.findall("\d","%s"%value4))    print(re.findall("\D","%s"%value4))    value5 = "alex\neric\t\negon\n"    print(re.findall("\n","%s"%value5))    print(re.findall("\t","%s"%value5))    print(re.findall("^h","hello egon hao123"))    print(re.findall("^h", "ello egon hao123"))    print(re.findall("3$","e3llo e3gon hao123"))    print(re.findall("3$", "e3llo e3gon hao12"))    print(re.findall("a.c","abc a1c a*c a|c abd aed ac"))    print(re.findall("a.c", "abc a1c a*c a|c abd aed a\nc",re.S))    print(re.findall("a[1,2\n]c","a2c a,c abc a1c a*c a|c abd aed a\nc"))    print(re.findall("a[0-9]c","a2c a,c a-c a1c a|c abd aed a\nc"))    print(re.findall("a[0-9a-zA-Z*-]c","a1c abc a*c a-c aEc azhangc"))    print(re.findall("a[^0-9]c","a1c abc a*c a-c aEc"))    print(re.findall("ab*","a b ac abc abbc"))    print(re.findall("ab[123]","abbbbb123"))    print(re.findall("ab[123]","ab1 ab2 abc3 abc1"))    print(re.findall("ab[123]+","ab1 ab2 ab33 abc11"))    print(re.findall("ab{3}","ab1 abbbbb2 abbbb3 ab4 ab122"))    print(re.findall("ab{3,4}","ab1 abbb123 abbbb123 abbbbbt"))    print(re.findall("ab{3,}", "ab1 abbb123 abbbb123 abbbbbt"))    print(re.findall("ab{0,}","a ab1 abbb123 abbbb123 abbbbbt"))    print(re.findall("ab{1,}", "a ab1 abbb123 abbbb123 abbbbbt"))    print(re.findall("ab?c","ac abc aec a1c"))    print(re.findall("ab{0,1}c", "ac abc aec a1c"))    print(re.findall("a.*c","ac abc aec a1c"))   #注意:结果不是['ac' ,'abc', 'aec', 'a1c']    #我感觉上面老师的解释似乎有点不对?    print(re.findall("a.*?c", "ac abc aec a1c")) #注意:结果是['ac' ,'abc', 'aec', 'a1c']    print(re.findall("a.*?c","ac abc a111111c a\nc a1c",re.S))    print(re.findall("compan(y|ies)","many companies have company"))    #?:可以匹配到完整的意思    print(re.findall("compan(?:y|ies)", "many companies have company"))    print(re.findall("ab+123","ababab123"))    print(re.findall("(ab)+123","ababab123"))    print(re.findall("(?:ab)+123", "ababab123"))    print(re.findall(r'a\\c', 'a\c'))

运行结果:

['a', 's', '2', '1', '3', 'd', 'f', '_']['*', '|']['a_b', 'a3b', 'aEb'][' ', '\n', '\t']['a', 'b', 'c', 'd']['1', '2', '3']['a', 'b', 'c', 'd', 'e', 'f']['\n', '\n', '\n']['\t']['h'][]['3'][]['abc', 'a1c', 'a*c', 'a|c']['abc', 'a1c', 'a*c', 'a|c', 'a\nc']['a2c', 'a,c', 'a1c', 'a\nc']['a2c', 'a1c']['a1c', 'abc', 'a*c', 'a-c', 'aEc']['abc', 'a*c', 'a-c', 'aEc']['a', 'a', 'ab', 'abb'][]['ab1', 'ab2']['ab1', 'ab2', 'ab33']['abbb', 'abbb']['abbb', 'abbbb', 'abbbb']['abbb', 'abbbb', 'abbbbb']['a', 'ab', 'abbb', 'abbbb', 'abbbbb']['ab', 'abbb', 'abbbb', 'abbbbb']['ac', 'abc']['ac', 'abc']['ac abc aec a1c']['ac', 'abc', 'aec', 'a1c']['ac', 'abc', 'a111111c', 'a\nc', 'a1c']['ies', 'y']['companies', 'company']['ab123']['ab']['ababab123']['a\\c']Process finished with exit code 0
原创粉丝点击