一、递归与二分法

一、递归

  1、递归调用的定义

  递归调用:在调用一个函数的过程中,直接或间接地调用了函数本身

  2、递归分为两类:直接与间接

  1. #直接
  2. def func():
  3. print('from func')
  4. func()
  5.  
  6. func()
  7. # 间接
  8. def foo():
  9. print('from foo')
  10. bar()
  11.  
  12. def bar():
  13. print('from bar')
  14. foo()
  15.  
  16. foo()

  3、递归调用的特点和使用的注意点

  1. 递归调用:在调用一个函数的过程中,直接或间接地调用了函数本身
  2. python中的递归效率低,需要在进入下一次递归时保留当前的状态
  3. 在其他语言中可以有解决方法:尾递归优化,即在函数的最后一步(而非最后一行)调用自己,尾递归优化:http://egon09.blog.51cto.com/9161406/1842475;但是python又没有尾递归,且对递归层级做了限制
  4.  
  5. #总结递归的使用:
  6. 1. 必须有一个明确的结束条件
  7. 2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
  8. 3. 递归效率不高,递归层次过多会导致栈溢出
  9. 在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出

  4、递归的执行分为两个阶段:递推(询问的过程)和回溯(回答的过程)

  1. #获知age(5)的值
  2. # age(5)=age(4)+2
  3. # age(4)=age(3)+2
  4. # age(3)=age(2)+2
  5. # age(2)=age(1)+2
  6. # age(1)=18
  7. #
  8. # age(n)=age(n-1)+2 #n>1
  9. # age(1)=18 #n=1
  10.  
  11. def age(n):
  12. if n == 1:
  13. return 18
  14. return age(n-1)+2
  15.  
  16. print(age(5))

  5、可以递归的最大深度

  1. #虽然可以设置,但是因为不是尾递归,仍然要保存栈,内存大小一定,不可能无限递归
  2. import sys
  3. sys.getrecursionlimit() ##获取目前默认递归的最大深度,默认深度是1000
  4. sys.setrecursionlimit(500) ##更改默认递归的最大深度
  5. n=1
  6. def test():
  7. global n
  8. print(n)
  9. n+=1
  10. test()
  11. test()

  6、应用场景:有许多层的列表,要取出所有元素——设置结束条件使用递归

  1. l =[1, 2,'list' ,[3, [4, 5, 6, [7, 8, [9, 10, [11, 12, 13, [14, 15,[16,[17,]],19]]]]]]]
  2. def search(l):
  3. for item in l:
  4. # if type(item) is list:
  5. if isinstance(item,list): ##判断数据类型是否是列表
  6. search(item)
  7. else:
  8. print(item)
  9.  
  10. search(l)

二、二分法

  1、二分法的产生

  1. 一个按照从小到大排列的数字列表中找到指定的数字,遍历的效率太低,用二分法(算法的一种,算法是解决问题的方法)可以极大低缩小问题规模

  2、 二分法的作用:不断将列表切分成两份,减小压力

  1. l = [1,2,5,6,77,1001,1165,2340]
  2. def search(l,num):
  3. print(l)
  4. if len(l) > 1:
  5. mid_index = len(l) // 2 #相除取整
  6. if num > l[mid_index]:
  7. #in the right
  8. l = l[mid_index+1:]
  9. elif num < l[mid_index]:
  10. #in the left
  11. l = l[:mid_index]
  12. else:
  13. print('find it')
  14. return
  15. else:
  16. if l[0] == num:
  17. print('find it')
  18. else:
  19. print('not exists')
  20. return
  21. search(l,num)
  22. search(l,77)

二、匿名函数

一、什么是匿名函数

  1. # 有名函数
  2. def f1(m):
  3. print(f1(3))
  4. # 匿名函数
  5. lambda n:n*2

二、匿名函数的应用场景

  1. 匿名函数自带return,只能使用一次
  2. #匿名函数即没有绑定名字的函数,意味着只能使用一次就会回收
  3. 应用场景:只使用一次的功能

三、匿名函数的使用

  1. salaries={
  2. 'egon':3000,
  3. 'alex':10000000,
  4. 'wupeiqi':10000,
  5. 'yuanhao':2000
  6. }
  7.  
  8. def f1(k):
  9. return salaries[k]

  1、max、min与 lambda结合

  1. print(max(salaries,key=lambda k:salaries[k]))
  2. print(min(salaries,key=lambda k:salaries[k]))

  2、sorted与lambda结合

  1. print(sorted(salaries,key=lambda k:salaries[k]))
  2. print(sorted(salaries,key=lambda k:salaries[k],reverse=True))

  3、map(映射)与lambda结合

  将原来的元素进行处理后,重新赋值给原变量

  1. l=['alex','egon','wzs','yuanhao']
  2. print(list(map(lambda x:x+'',l)))

  4、reduce(合并)与lambda结合

  计算0到100数字的和

  1. from functools import reduce
  2. # reduce(lambda 表达式,计算范围,计算的初始值)
  3. res=reduce(lambda x,y:x+y,range(1,100),100)
  4. print(res)

  5、filter(过滤)与lambda结合

  过滤出列表中以123结尾的元素

  1. l=['alex123','egon123','wzs123','yuanhao']
  2. print(list(filter(lambda name:name.endswith(''),l)))

  6、扩展: 拉链函数

  1. l1=[1,2,3]
  2. s1='hello'
  3. res = zip(l1,s1)
  4. print(list(res))
  5.  
  6. res=zip(salaries.values(),salaries.keys())
  7. print(max(res)[1])
  1. t1=(111,'a')
  2. t2=(11,'b',123,'c')
  3. print(t1 < t2)

元素比较大小:从左到右比较元素的大小

三、内置函数

一、什么是内置函数

  1. 内置函数:python将简单的功能内置到语言中,使用者不用定义,可以直接使用
    内置函数链接:https://docs.python.org/3/library/functions.html?highlight=built#ascii

二、常用的内置函数

  

  友情链接:http://www.cnblogs.com/xiao1/p/5856890.html

  1、优先掌握的函数

  1. max min sorted map filter sum bool chr divmod enumerate
  2. id input print isinstance iter len open pow type zip
  3. from _functools import reduce

  2、数学运算

  1. abs(-5) # 取绝对值,也就是5
  2. round(2.6) # 四舍五入取整,也就是3.0
  3. pow(2, 3) # 相当于2**3,如果是pow(2, 3, 5),相当于2**3 % 5
  4. cmp(2.3, 3.2) # 比较两个数的大小
  5. divmod(9,2) # 返回除法结果和余数,分页显示内容,计算页数
    max([1,5,2,9]) # 求最大值 min([9,2,-4,2]) # 求最小值 sum([2,-1,9,12]) # 求和

  3、类型转换

  1. int("") # 转换为整数 integer
  2. float(2) # 转换为浮点数 float
  3. long("") # 转换为长整数 long integer
  4. str(2.3) # 转换为字符串 string
  5. complex(3, 9) # 返回复数 3 + 9i
  6. bytes() # 字节
  7. list((1,2,3)) # 转换为表 list
  8. tuple([2,3,4]) # 转换为定值表 tuple
  9. dict(a=1,b="hello",c=[1,2,3]) # 构建词典 dictionary
  10. set() # 转换成集合
  11. slice(5,2,-1) # 切片操作
  1. # bytes object
  2. b = b"example"
  3. # str object
  4. s = "example"
  5. # str to bytes
  6. sb = bytes(s, encoding = "utf8")
  7. print(type(sb))
  8. # bytes to str
  9. bs = str(b, encoding = "utf8")
  10. # an alternative(可替代的方法) method
  11. # str to bytes
  12. sb2 = str.encode(s)
  13. # bytes to str
  14. bs2 = bytes.decode(b)

python str与bytes之间的转换

  ASCII表中的字符和序号之间互相转好,应用场景:生成随机验证码

  1. #65-90是大写A-Z
  2. print(chr(65))
  3. print(chr(90))
  4. #97-122是小写a-z
  5. print(chr(97))
  6. print(chr(122))
  7. print(ord('A'))
  8. #48-57是数字0-9
  9. print(chr(48))
  10. print(chr(57))

  bool()布尔判断,在python中,为False的情况:空(字符 ‘’,列表 [],元组 (),字典 {}),0,0.0,None

  1. bool(0) # 转换为相应的真假值,在Python中,0相当于False

  进制显示

  1. bin(56) # 返回一个字符串,表示56的二进制数
  2. hex(56) # 返回一个字符串,表示56的十六进制数
  3. oct(56) # 返回一个字符串,表示56的八进制数

  判断元素是否为True

  1. all([True, 1, "hello!"]) # 是否所有的元素都相当于True值
  2. any(["", 0, False, [], None]) # 是否有任意一个元素相当于True值

  排序

  1. sorted([1,5,3]) # 返回正序的序列,也就是[1,3,5]
  2. reversed([1,5,3]) # 返回反序的序列,也就是[3,5,1]

  4、类、对象、属性

  1. # define class
  2. class Me(object):
  3. def test(self):
  4. print "Hello!"
  5. def new_test():
  6. print "New Hello!"
  7. me = Me()
  1. object()
    hasattr(me, "test") # 检查me对象是否有test属性
  2. getattr(me, "test") # 返回test属性
  3. setattr(me, "test", new_test) # 将test属性设置为new_test
  4. delattr(me, "test") # 删除test属性
  5. isinstance(1,int) # 检查对象是否是类的对象,返回True或False
  6. issubclass(Me, object) # Me类是否为object类的子类

  5、hash哈希值 :应用——数据校验

  1. hash(object)
  2. 如果对象object为哈希表类型,返回对象object的哈希值。哈希值为整数,在字典查找中,哈希值用于快递比价字典的键。
  3. 两个数值如果相等,则哈希值也相等。

  6、名称空间 局部名称vars()、locals(),全局名称空间global(),显示形式是字典

  1. print(vars() is locals())
  2. print(globals())

  7、__import__()  可以导入字符串,import不能导入字符串

  1. # import "time" #不能导入字符串
  2. # import time
  3. m=input('>>:')
  4. print(type(m))
  5. obj=__import__(m) ##这样就可以导入字符串了
  6. obj.sleep(2)
  7. print(m)

  8、compile编译,执行exec、eval (了解)

    1、compile编译

  语法

  1. compile(str,filename,kind)
  2. filename:用于追踪str来自于哪个文件,如果不想追踪就可以不定义
  3. kind可以是:single代表一条语句,exec代表一组语句,eval代表一个表达式

  应用

  1. s="for i in range(10):print(i)"
  2. code=compile(s,'','exec')
  3. exec(code) ##有返回结果
  4.  
  5. s1="1+2+3"
  6. code1=compile(s1,'','eval')
  7. eval(code1) ##没有返回结果
    2、eval与exec

  eval 提取字符串内的表达式执行,并返回结果(可执行语句会报错)
  exec 执行字符串内的表达式或语句,没有返回结果

  语法

  1. eval(str,[,globals[,locals]])
  2. exec(str,[,globals[,locals]])

  举例

  1. s1="1+2+3"
  2. # s1="['a','b','c']"
  3. s2="for i in range(10):print (i)"
  4. print(eval(s1))
  5. print(exec(s1))
  6. print(exec(s2))

四、模块

一、模块介绍

  1、什么是模块

  1. 一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀。

  2、为何使用模块

  1. 如果你退出python解释器然后重新进入,那么你之前定义的函数或者变量都将丢失,因此我们通常将程序写到文件中以便永久保存下来,需要时就通过python test.py方式去执行,此时test.py被称为脚本script
  2. 随着程序的发展,功能越来越多,为了方便管理,我们通常将程序分成一个个的文件,这样做程序的结构更清晰,方便管理。这时我们不仅仅可以把这些文件当做脚本去执行,还可以把他们当做模块来导入到其他的模块中,实现了功能的重复利用

  import加载的模块分为四个通用类别

  1. 1、使用python编写的代码(.py文件)
  2. 2、已被编译为共享库或DLLCC++扩展
  3. 3、好一组模块的包
  4. 4、使用C编写并链接到python解释器的内置模块

  3、导入模块都干了哪些事?

  1. 1、执行源文件
  2. 2、以一个源文件的全局名称空间
  3. 3、在当前位置拿到一个模块名,指向2创建的名称空间

  4、python文件的两种用途

  1. .py文件的两种用途:1、当做脚本运行 2、当做模块被加载运行
  2.  
  3. 文件当做脚本运行时,__name__等于__main__
  4. 文件当做模块被加载运行时,__name__等于模块名
  1. if __name__ == '__main__':
  2. # 当做脚本使用
  3. func1()
  4. func2()
  5. func3()
  6. # main #回车会导入if __name__ == '__main__':

二、使用import导入模块

  模块代码文件:spam.py

  1. #spam.py
  2. # print('from the spam.py')
  3. # 限制*的导入内容
  4. # _money=1000 #对*隐藏,即*无法调用(from spam import *)
  5. # __all__ = ['money','x'] # *只能调用赋予给__all__的名称 (from spam import *)
  6. money=10000000000000
  7. def read1():
  8. print('spam->read1->money',money)
  9.  
  10. def read2():
  11. print('spam->read2 calling read')
  12. read1()
  13.  
  14. def change():
  15. global money
  16. money=0

  1、导入模块并执行

  test.py

  1. import spam
  2. money=100
  3. spam.read1()
  4. spam.read2()
  5. spam.change()
  6. spam.read1()
  7. print(money)

  2、as取别名

    用途:1、模块名非常长; 2、更改模块的功能

  测试文件

  1. def sqlparse():
  2. print('mysql sqlparse')

mysql.py

  1. def sqlparse():
  2. print('oracle sqlparse')

oracle.py

  导入模块,并执行

  1. import spam as s1
  2. money = 10000000
  3. spam.change()
  4. print(spam.money)

模块名比较长

  1. sql_type = input('sql_type>>')
  2. if sql_type == 'mysql':
  3. import mysql as sql ##引用不同的模块,因为实现的功能是相同的,所以可以起相同的别名
  4. elif sql_type == 'oracle':
  5. import oracle as sql
  6. sql.sqlparse()

传入的内容调用不同的模块

  3、导入多个模块:模块之间用逗号隔开(不建议这么写,还是不同模块分行写为好)

  1. import os,sys,requests

  4、模块导入的特点

  模块只在第一次导入时才会执行,之后的导入都是直接引用内存已经存在的结果

  1. import spam
  2. import spam
  3. import spam
  4. import spam
  5.  
  6. #验证是否已经在内存
  7. import sys
  8. # print(sys.modules) #存放的是已经加到内存的模块
  9. print('spam' in sys.modules) #查看一个模块是否加到内存中
  10. import spam
  11. print('spam' in sys.modules)

导入,并验证是否已在内存中

三、from....import...导入模块

  1、对比import导入模块,from....import...的优缺点

  1. 对比import spam,会将源文件的名称空间'spam'带到当前名称空间中,使用时必须是spam.名字的方式
  2. from 语句相当于import,也会创建新的名称空间,但是将spam中的名字直接导入到当前的名称空间中,在当前名称空间中,直接使用名字就可以了
  3. 优点:使用源文件内的名字时,无需加前缀,使用方便
  4. 缺点:容易与当前文件的名称空间内的名字混淆,会覆盖原来名字的值

  2、语法范例

  1. from spam import money,read1,read2
  2. money = 10
  3. print(money)
  4. # g=read1()
  5. g=read2()
  6. print(g)

  3、将模块导入并起别名

  1. # # from spam import read1 as m
  2. from spam import money as m
  3. # print(m)

  4、*的使用  (不建议使用*)

  1. #要引用的源文件里面的内容很多时,可以使用*代替所有(更容易与当前文件的名称空间冲突),但是不建议使用
  2.  
  3. _money=1000 #将调用的名字前面加_,*就无法调用该名字(在源文件修改)
  4. __all__ = ['money','x'] # *只能调用赋予给__all__的名称(在源文件修改)
  5. from spam import *

四、模块的搜索路径

  1、模块查找的顺序

  1. 查找顺序:内存---->>内置模块---->>硬盘

  范例

  1. import time
  2. import importlib
  3. import spam
  4. time.sleep(30)
  5. # import spam
  6. # print(spam.money)
  7.  
  8. importlib.reload(spam) ##重启加载spam,可以使用到测试环境
  9. print(spam.money)

  2、模块的注意事项

  1. 注意:
  2. 1Python程序只有重新加载才能生效
  3. 2Python自带的模块名不能使用

  3、搜索路径和注意事项

  1. 当一个命名为spam的模块被导入时
  2. 解释器首先会从内建模块中寻找该名字
  3. 找不到,则去sys.path中找该名字
  4. sys.path从以下位置初始化
  5. 1 执行文件所在的当前目录
  6. 2 PTYHONPATH(包含一系列目录名,与shell变量PATH语法一样)
  7. 3 依赖安装时默认指定的
  8. 注意:在支持软连接的文件系统中,执行脚本所在的目录是在软连接之后被计算的,换句话说,包含软连接的目录不会被添加到模块的搜索路径中
  9. 在初始化后,我们也可以在python程序中修改sys.path,执行文件所在的路径默认是sys.path的第一个目录,在所有标准库路径的前面。这意味着,当前目录是优先于标准库目录的,需要强调的是:我们自定义的模块名不要跟python标准库的模块名重复

  4、添加到path环境变量

  1. import sys
  2. print(sys.path)
  3. # 添加path环境变量
  4. # 加到最后面
  5. sys.path.append(r'G:\data\PyCharm_Project\s19\day5\模块\模块的搜索路径\aaa')
  6. # 加到最前面
  7. sys.path.insert(0,r'G:\data\PyCharm_Project\s19\day5\模块\模块的搜索路径\aaa')
  8.  
  9. import spam
  10.  
  11. from aaa import #模块的搜索路径

五、模块的重载

  考虑到性能的原因,每个模块只被导入一次,放入字典sys.module中,如果你改变了模块的内容,你必须重启程序,python不支持重新加载或卸载之前导入的模块

  有的同学可能会想到直接从sys.module中删除一个模块不就可以卸载了吗,注意了,你删了sys.module中的模块对象仍然可能被其他程序的组件所引用,因而不会被清楚。

  特别的对于我们引用了这个模块中的一个类,用这个类产生了很多对象,因而这些对象都有关于这个模块的引用。

  如果只是你想交互测试的一个模块,使用 importlib.reload(), e.g. import importlib; importlib.reload(modulename),这只能用于测试环境。

  1. def func1():
  2. print('func1')

aa.py

  1. import time,importlib
  2. import aa
  3.  
  4. time.sleep(20)
  5. # importlib.reload(aa)
  6. aa.func1()

reload.py

五、包

  http://www.cnblogs.com/linhaifeng/articles/6379069.html

一、包的简介

  1、什么是包

  1. ##官网的解释
  2. 包是一种通过使用‘.模块名’来组织Python模块名称空间的方式
  3. ##详细解释
  4. 包就是一个含有__init__.py文件的文件夹,所以我们创建包的目的就是为了用文件/模块组织起来。
  5. 1. 无论是import形式还是from...import形式,凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高警觉:这是关于包才有的导入语法
  6. 2. 包是目录级的(文件夹级),文件夹是用来组成py文件(包的本质就是一个包含__init__.py文件的目录)
  7. 3. import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件
  8. ##强调:
  9.   1. python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错
  10.   2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包即模块
  11. A和包B下有同名模块也不会冲突,如A.aB.a来自俩个命名空间

  2、为何要使用包

  1. 随着功能越写越多,我们无法将所有功能都放到一个文件中,于是我们使用模块去组织功能,而随着模块越来越多,我们需要用文件夹将模块文件组织起来,依次来提供程序的结构性和可维护性

  3、注意事项

  1. .关于包相关的导入语句也分为importfrom ... import ...两种,但是无论哪种,无论在什么位置,在导入时都必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包,否则非法。可以带有一连串的点,如item.subitem.subsubitem,但都必须遵循这个原则。
  2. .对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)。
  3. .对比import item from item import name的应用场景:
  4. 如果我们想直接使用name那必须使用后者。

  4、上课流程

  1. 实验一
  2. 准备:
  3. 执行文件为test.py,内容
  4. #test.py
  5. import aaa
  6. 同级目录下创建目录aaa,然后自建空__init__.py(或者干脆建包)
  7.  
  8. 需求:验证导入包就是在导入包下的__init__.py
  9.  
  10. 解决:
  11. 先执行看结果
  12. 再在__init__.py添加打印信息后,重新执行
  13.  
  14. 2、实验二
  15. 准备:基于上面的结果
  16.  
  17. 需求:
  18. aaa.x
  19. aaa.y
  20. 解决:在__init__.py中定义名字xy
  21.  
  22. 3、实验三
  23. 准备:在aaa下建立m1.pym2.py
  24. #m1.py
  25. def f1():
  26. print('from 1')
  27. #m2.py
  28. def f2():
  29. print('from 2')
  30. 需求:
  31. aaa.m1 #进而aaa.m1.func1()
  32. aaa.m2 #进而aaa.m2.func2()
  33.  
  34. 解决:在__init__.py中定义名字m1m2,先定义一个普通变量,再引出如何导入模块名,强调:环境变量是以执行文件为准
  35.  
  36. 4、实验四
  37. 准备:在aaa下新建包bbb
  38.  
  39. 需求:
  40. aaa.bbb
  41.  
  42. 解决:在aaa__init__.py内导入名字bbb
  43.  
  44. 5、实验五
  45. 准备:
  46. bbb下建立模块m3.py
  47. #m3.py
  48. def f3():
  49. print('from 3')
  50. 需求:
  51. aaa.bbb.m3 #进而aaa.bbb.m3.f3()
  52.  
  53. 解决:是bbb下的名字m3,因而要在bbb__init__.py文件中导入名字m3from aaa.bbb import m3
  54.  
  55. 6、实验六
  56. 准备:基于上面的结果
  57.  
  58. 需求:
  59. aaa.m1()
  60. aaa.m2()
  61. aaa.m3()
  62. 进而实现
  63. aaa.f1()
  64. aaa.f2()
  65. aaa.f3()
  66. 先用绝对导入,再用相对导入
  67.  
  68. 解决:在aaa__init__.py中拿到名字m1m2m3
  69. 包内模块直接的相对导入,强调包的本质:包内的模块是用来被导入的,而不是被执行的
  70. 用户无法区分模块是文件还是一个包,我们定义包是为了方便开发者维护
  71.  
  72. 7、实验七
  73. 将包整理当做一个模块,移动到别的目录下,操作sys.path

二、包的使用

  1、测试文件:执行文件与测试文件在同级目录下


  1. ├── aaa
  2.    ├── bbb
  3.       ├── __init__.py
  4.       ├── m3.py
  5.       └── __pycache__
  6.    ├── __init__.py
  7.    ├── m1.py
  8.    ├── m2.py
  9.    └── __pycache__
  10. └── run.py
  1. ##文件内容
  2.  
  3. #m1.py
  4. def func1():
  5. print('f1')
  6.  
  7. #m2.py
  8. def func2():
  9. print('f2')
  10.  
  11. #m3.py
  12. def func3():
  13. print('f3')

文件内容

  2、包的使用之import

  单独导入包名称时,不会导入包中的所有包含的所有子模块

  1. #在与aaa同级的run.py
  2. import aaa
  3. aaa.m1.func1()
  4.  
  5. 执行结果会出现如下错误:
  6. ModuleNotFoundError: No module named 'm1'

  解决方法

  1. #与aaa底下的__init__.py
  2. from .m1 import func1
  3.  
  4. #导入模块,执行aaa同级的run.py的结果
  5. import aaa
  6.  
  7. f1

  需要注意的:

  from后import导入的模块,必须是明确的一个不能带点,否则会有语法错误,如:from a import b.c是错误语法

    from aaa.bbb.m3 import func3

  3、from aaa.bbb.m3 import * :从一个包中导入所有*

 想从包api中导入所有,实际上该语句只会导入包api下__init__.py文件中定义的名字,我们可以在这个文件中定义__all___:

  1. #在__init__.py中定义
  2. x=10
  3.  
  4. def func():
  5. print('from api.__init.py')
  6.  
  7. __all__=['x','func','policy']

  4、绝对导入和相对导入

  最顶级包是aaa是给用户使用的,然后在aaa内部也会有彼此之间相互导入的需求,这时就有绝对和相对导入两种方式。

  绝对导入:以aaa作为起始

  相对导入:用.或者..的方式最为起始(只能在一个包中使用,不能用于不同目录内)

  

  1.    例:想在aaa/bbb/func3.py中导入aaa/ccc/func4.py
  2.  
  3. 绝对导入
  4. func3.py上写入下面的代码
  5. from aaa.ccc.m4 import func4
  6. run.py同级的__init__.pyd导入相应的模块
  7. from aaa.bbb.m3 import func4
  8. run.py上的写入下面的代码直接调用
  9. aaa.func4()
  10.  
  11. 相对导入
  12. func4.py上写入下面的代码
  13. from ..ccc.m4 import func4
  14. run.py同级的__init__.pyd导入相应的模块
  15. from aaa.bbb.m3 import func4
  16. run.py上的写入下面的代码直接调用
  17. aaa.func4()

  5、包以及包所包含的模块都是用来被导入的,而不是被直接执行的。而环境变量都是以执行文件为准的

  添加环境变量

  1. import sys
  2. sys.path.append(r'C:\Users\CTB-BJB-0012\PycharmProjects\python36\s19\day5\包\xxx\yyy')
  3. import aaa
  1. from .m1 import func1
  2. from .m2 import func2
  3. from .bbb.m3 import func3
  4. from .bbb.m3 import func4

aaa同级的__init__.py内容

  1. from ..ccc.m4 import func4
  2. def func3():
  3. print('f3')
  4. func4()

m3.py文件内容

  1. import sys
  2. sys.path.append(r'C:\Users\CTB-BJB-0012\PycharmProjects\python36\s19\day5\包\xxx\yyy')
  3. import aaa
  4. aaa.func1()
  5. aaa.func2()
  6. aaa.func3()

运行run.py文件内容

  运行文件使用import直接导入所需模块的功能(使用了解目录结构):

    导入:import aaa.ccc.m4

    调用:aaa.ccc.c4.func4()

  6、包的分发(了解)

  学习链接网址:https://packaging.python.org/tutorials/distributing-packages/

六、软件开发规范

一、软件目录规范如下

  

二、常用模块的使用

  1. #=============>bin目录:存放执行脚本
  2. #start.py
  3. import sys,os
  4.  
  5. BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  6. sys.path.append(BASE_DIR)
  7.  
  8. from core import core
  9. from conf import my_log_settings
  10.  
  11. if __name__ == '__main__':
  12. my_log_settings.load_my_logging_cfg()
  13. core.run()
  14.  
  15. #=============>conf目录:存放配置文件
  16. #config.ini
  17. [DEFAULT]
  18. user_timeout = 1000
  19.  
  20. [egon]
  21. password = 123
  22. money = 10000000
  23.  
  24. [alex]
  25. password = alex3714
  26. money=10000000000
  27.  
  28. [yuanhao]
  29. password = ysb123
  30. money=10
  31.  
  32. #settings.py
  33. import os
  34. config_path=r'%s\%s' %(os.path.dirname(os.path.abspath(__file__)),'config.ini')
  35. user_timeout=10
  36. user_db_path=r'%s\%s' %(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),\
  37. 'db')
  38.  
  39. #my_log_settings.py
  40. """
  41. logging配置
  42. """
  43.  
  44. import os
  45. import logging.config
  46.  
  47. # 定义三种日志输出格式 开始
  48.  
  49. standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
  50. '[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字
  51.  
  52. simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
  53.  
  54. id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'
  55.  
  56. # 定义日志输出格式 结束
  57.  
  58. logfile_dir = r'%s\log' %os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # log文件的目录
  59.  
  60. logfile_name = 'all2.log' # log文件名
  61.  
  62. # 如果不存在定义的日志目录就创建一个
  63. if not os.path.isdir(logfile_dir):
  64. os.mkdir(logfile_dir)
  65.  
  66. # log文件的全路径
  67. logfile_path = os.path.join(logfile_dir, logfile_name)
  68.  
  69. # log配置字典
  70. LOGGING_DIC = {
  71. 'version': 1,
  72. 'disable_existing_loggers': False,
  73. 'formatters': {
  74. 'standard': {
  75. 'format': standard_format
  76. },
  77. 'simple': {
  78. 'format': simple_format
  79. },
  80. },
  81. 'filters': {},
  82. 'handlers': {
  83. #打印到终端的日志
  84. 'console': {
  85. 'level': 'DEBUG',
  86. 'class': 'logging.StreamHandler', # 打印到屏幕
  87. 'formatter': 'simple'
  88. },
  89. #打印到文件的日志,收集info及以上的日志
  90. 'default': {
  91. 'level': 'DEBUG',
  92. 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件
  93. 'formatter': 'standard',
  94. 'filename': logfile_path, # 日志文件
  95. 'maxBytes': 1024*1024*5, # 日志大小 5M
  96. 'backupCount': 5,
  97. 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
  98. },
  99. },
  100. 'loggers': {
  101. #logging.getLogger(__name__)拿到的logger配置
  102. '': {
  103. 'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
  104. 'level': 'DEBUG',
  105. 'propagate': True, # 向上(更高level的logger)传递
  106. },
  107. },
  108. }
  109.  
  110. def load_my_logging_cfg():
  111. logging.config.dictConfig(LOGGING_DIC) # 导入上面定义的logging配置
  112. logger = logging.getLogger(__name__) # 生成一个log实例
  113. logger.info('It works!') # 记录该文件的运行状态
  114.  
  115. if __name__ == '__main__':
  116. load_my_logging_cfg()
  117.  
  118. #=============>core目录:存放核心逻辑
  119. #core.py
  120. import logging
  121. import time
  122. from conf import settings
  123. from lib import read_ini
  124.  
  125. config=read_ini.read(settings.config_path)
  126. logger=logging.getLogger(__name__)
  127.  
  128. current_user={'user':None,'login_time':None,'timeout':int(settings.user_timeout)}
  129. def auth(func):
  130. def wrapper(*args,**kwargs):
  131. if current_user['user']:
  132. interval=time.time()-current_user['login_time']
  133. if interval < current_user['timeout']:
  134. return func(*args,**kwargs)
  135. name = input('name>>: ')
  136. password = input('password>>: ')
  137. if config.has_section(name):
  138. if password == config.get(name,'password'):
  139. logger.info('登录成功')
  140. current_user['user']=name
  141. current_user['login_time']=time.time()
  142. return func(*args,**kwargs)
  143. else:
  144. logger.error('用户名不存在')
  145.  
  146. return wrapper
  147.  
  148. @auth
  149. def buy():
  150. print('buy...')
  151.  
  152. @auth
  153. def run():
  154.  
  155. print('''
  156. 购物
  157. 查看余额
  158. 转账
  159. ''')
  160. while True:
  161. choice = input('>>: ').strip()
  162. if not choice:continue
  163. if choice == '':
  164. buy()
  165.  
  166. if __name__ == '__main__':
  167. run()
  168.  
  169. #=============>db目录:存放数据库文件
  170. #alex_json
  171. #egon_json
  172.  
  173. #=============>lib目录:存放自定义的模块与包
  174. #read_ini.py
  175. import configparser
  176. def read(config_file):
  177. config=configparser.ConfigParser()
  178. config.read(config_file)
  179. return config
  180.  
  181. #=============>log目录:存放日志
  182. #all2.log
  183. [2017-07-29 00:31:40,272][MainThread:11692][task_id:conf.my_log_settings][my_log_settings.py:75][INFO][It works!]
  184. [2017-07-29 00:31:41,789][MainThread:11692][task_id:core.core][core.py:25][ERROR][用户名不存在]
  185. [2017-07-29 00:31:46,394][MainThread:12348][task_id:conf.my_log_settings][my_log_settings.py:75][INFO][It works!]
  186. [2017-07-29 00:31:47,629][MainThread:12348][task_id:core.core][core.py:25][ERROR][用户名不存在]
  187. [2017-07-29 00:31:57,912][MainThread:10528][task_id:conf.my_log_settings][my_log_settings.py:75][INFO][It works!]
  188. [2017-07-29 00:32:03,340][MainThread:12744][task_id:conf.my_log_settings][my_log_settings.py:75][INFO][It works!]
  189. [2017-07-29 00:32:05,065][MainThread:12916][task_id:conf.my_log_settings][my_log_settings.py:75][INFO][It works!]
  190. [2017-07-29 00:32:08,181][MainThread:12916][task_id:core.core][core.py:25][ERROR][用户名不存在]
  191. [2017-07-29 00:32:13,638][MainThread:7220][task_id:conf.my_log_settings][my_log_settings.py:75][INFO][It works!]
  192. [2017-07-29 00:32:23,005][MainThread:7220][task_id:core.core][core.py:20][INFO][登录成功]
  193. [2017-07-29 00:32:40,941][MainThread:7220][task_id:core.core][core.py:20][INFO][登录成功]
  194. [2017-07-29 00:32:47,222][MainThread:7220][task_id:core.core][core.py:20][INFO][登录成功]
  195. [2017-07-29 00:32:51,949][MainThread:7220][task_id:core.core][core.py:25][ERROR][用户名不存在]
  196. [2017-07-29 00:33:00,213][MainThread:7220][task_id:core.core][core.py:20][INFO][登录成功]
  197. [2017-07-29 00:33:50,118][MainThread:8500][task_id:conf.my_log_settings][my_log_settings.py:75][INFO][It works!]
  198. [2017-07-29 00:33:55,845][MainThread:8500][task_id:core.core][core.py:20][INFO][登录成功]
  199. [2017-07-29 00:34:06,837][MainThread:8500][task_id:core.core][core.py:25][ERROR][用户名不存在]
  200. [2017-07-29 00:34:09,405][MainThread:8500][task_id:core.core][core.py:25][ERROR][用户名不存在]
  201. [2017-07-29 00:34:10,645][MainThread:8500][task_id:core.core][core.py:25][ERROR][用户名不存在]

常用模块的使用

Day5 函数递归,匿名、内置行数,模块和包,开发规范的更多相关文章

  1. py基础3--函数,递归,内置函数

    本节内容 函数基本语法及特性 参数与局部变量 返回值 嵌套函数 递归 匿名函数 函数式编程介绍 高阶函数 内置函数 1. 函数基本语法及特性 背景提要 现在老板让你写一个监控程序,监控服务器的系统状况 ...

  2. python自动化day3-函数、递归、内置函数

    一.什么是函数 修理工===>程序员 具备某一功能的工具===>函数 要想使用工具,需要事先准备好,然后拿来就用且可以重复使用要想用函数,需要先定义,再使用 二.函数基础 1.函数分类 # ...

  3. 简学Python第三章__函数式编程、递归、内置函数

    #cnblogs_post_body h2 { background: linear-gradient(to bottom, #18c0ff 0%,#0c7eff 100%); color: #fff ...

  4. 生成器的send方法、递推函数、匿名函数及常用内置函数

    生成器的send方法 在使用yield方法创建生成器时,不仅可以使用next方法进行取值,还可以通过send方法向生成器的内部传值 什么是send方法? send方法相当于高级的next方法,send ...

  5. python 函数 装饰器 内置函数

    函数 装饰器 内置函数 一.命名空间和作用域 二.装饰器 1.无参数 2.函数有参数 3.函数动态参数 4.装饰器参数 三.内置函数 salaries={ 'egon':3000, 'alex':10 ...

  6. 【Android】9.2 内置行视图的分类和呈现效果

    分类:C#.Android.VS2015: 创建日期:2016-02-18 一.简介 Android内置了很多行视图模板,在应用程序中可直接使用这些内置的视图来呈现列表项. 要在ListView中使用 ...

  7. JavaScript封装一个函数效果类似内置方法concat()

    JavaScript封装一个函数效果类似内置方法concat() 首先回忆concat()的作用: concat() 方法用于连接两个或多个数组.该方法不会改变现有的数组,而仅仅会返回被连接数组的一个 ...

  8. Python内置的操作系统模块(os)与解释器交互模块(sys)

    Python内置的操作系统模块(os)与解释器交互模块(sys) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本片博客只介绍Python调用操作系统的模块即os模块,以及Pyth ...

  9. Filebeat使用内置的mysql模块收集日志存储到ES集群并使用kibana存储

    Filebeat内置了不少的模块,可以直接使用他们对日志进行收集,支持的模块如下: [root@ELK-chaofeng07 logstash]# filebeat modules list Enab ...

随机推荐

  1. 如何用VBA实现格式刷的功能?

    1. http://club.excelhome.net/thread-373686-1-1.html 复制1格式Selection.CopyFormat粘贴格式Selection.PasteForm ...

  2. springMVC参数传递实例

    最好所有的post请求用postman这个工具就好了. postman传对象

  3. ajax 获取服务器返回的XML字符串

    前台 解析失败不会抛出任何异常, 只会返回一个给定的错误文档 let l = console.log let http = ajanuw.create({ uri: 'http://localhost ...

  4. Smarty模板保留缓存

    <?php //缓存 //注:使用缓存需要用到这几个方法: //(ob_start(开启内存缓存); ob_flush(清除内存缓存);) //file_exists这个方法是判断文件是否存在 ...

  5. Ajax请求参数较长导致请求失败

    Ajax请求参数比较长,第5行参数大概1100个字符吧,是接口的请求报文. $.ajax({ type:"POST", url:"${ctx}/test.action?m ...

  6. [No0000128]SQL纵表与横表互转

    1.纵表转横表: 纵表结构:Table1 转换后的横表结构: Sql示例代码: select username, sum(case Course when '语文' then Grade else 0 ...

  7. GlusterFS分布式存储系统中更换故障Brick的操作记录1

    前面已经介绍了GlusterFS分布式存储集群环境部署记录,现在模拟下更换故障Brick的操作: 1)GlusterFS集群系统一共有4个节点,集群信息如下: 分别在各个节点上配置hosts.同步好系 ...

  8. LU decomposition can be viewed as the matrix form of Gaussian elimination.

    https://en.wikipedia.org/wiki/LU_decomposition One way to find the LU decomposition of this simple m ...

  9. A Method for the Construction of Minimum-Redundancy Codes

    A Method for the Construction of Minimum-Redundancy Codes http://compression.ru/download/articles/hu ...

  10. Xcode报错Expected selector for Objective-C and Expected method body

    昨天把键盘拿起来拍一下清清灰,然后就发现Xcode报错了,Xcode报错Expected selector for Objective-C and Expected method body,也不知道什 ...