python装饰器,高阶函数,递归,栈和队列,遍历目录

装饰器

学习思路:
  a、如何定义装饰器
  b、装饰器的工作原理【系统的装饰器】

a、如何定义装饰器
"""
装饰器的本质:就是一个闭包,只不过改闭包的外部函数的参数为另一个函数【需要被装饰的函数】

在装饰器的使用过程中,应用到了函数的本质

装饰器的好处:可以在不用修改原函数的基础上,给指定的函数增加新的功能

"""
一个最简单的装饰器
def now():
    print("为了部落")


def wrapper(fun):
    print("外部函数用了哦")
    def inner():
        # 在inner中,调用原函数,增加新功能,顺序可以根据需求进行修改
		fun()
        print("新的功能")
    return inner
	print()
"""
wrapper被称为装饰器的名称
应用场景:统计函数的执行时间,日志处理,函数执行完毕的清理功能,权限校验,缓存的处理
"""
def test():
    for i in range(10):
        print()


def outter(fun1):
    def inner():
        fun1()
        '''

        for i in range(1,10):
            for j in range(1,i+1):
                print("%dx%d=%d"%(j,i,j*i),end=' ')
                print()
    return inner
f = outter(test)
f()
b、装饰器的工作原理
#有参数的装饰器 注意:使用 @装饰器名 作用于原函数,则装饰器必须先存在,才能修饰函数
def wrapper(f):
    def inner(age):
        if age < 0:
            age = -age

        #调用原函数
        f(age)
    return inner

@wrapper
def get_age(age):
    print("你的年龄是:%d"% age)
"""
# 一个装饰器作用于多个函数
# 多个不同的函数增加了同一个功能
"""


def wrapper(fun):
    def inner(*args, **kwargs):
        fun(*args, **kwargs)

        print("new")

    return inner


@wrapper
def func1():
    print("func~~~~111")

func1()         # func~~~~111   new


@wrapper
def func2(a):
    print("func~~~~222")

func2(0)           # func~~~~222   new

@wrapper
def func3(num1, num2, num3):
    print("func~~~~~333")


func3(10, 20, 30)    # func~~~~~333     new
"""
多个装饰器作用于同一个函数
# 给一个函数同时增加多个不同的功能

"""
#例1
def wrapper1(func1):
    def inner1():
        print("装饰器~~~111")
        func1()
    return inner1

def wrapper2(func2):
    def inner2():
        print("装饰器~~~~222")
        func2()
    return inner2

def wrapper3(func3):
    def inner3():
        print("装饰器~~~333")
        func3()
    return inner3

@wrapper1      #           第三步: func1 = show[show------inner2]   show = inner1
@wrapper2      #           第二步: func2 = show[show--->inner3]   show = inner2
@wrapper3      # 传参过程: 第一步: func3 = show  show = inner3
def show():
    print("showing")

show()       
"""
装饰器~~~111
装饰器~~~~222
装饰器~~~333
showing
"""
# 例2
def wrapper_1(func1):
    def inner1():
        print("装饰器~~~1111")
        func1()
    return inner1

def wrapper_2(func2):
    def inner2():
        print("装饰器~~~2222")
        func2()
    return inner2

def wrapper_3(func3):
    def inner3():
        print("装饰器~~~3333")
        func3()
    return inner3

@wrapper_1
@wrapper_3
@wrapper_2
def show():
    print("showing")
show()
"""
装饰器~~~1111
装饰器~~~3333
装饰器~~~2222
showing
"""
print("*" * 30)
"""

"""
a、当多个装饰器修饰同一个函数的时候,采用的就近原则,从上往下进行传参【一直改变原函数的指向】,从上往下执行
b、原函数都只会被执行一次
c、通过不断修改原函数的指向完成整个装饰器的调用过程
"""

def wrapper_1(func1):
    def inner1():
        print("装饰器~~~1111")
        func1()
    return inner1

def wrapper_2(func2):
    def inner2():
        func2()
        print("装饰器~~~2222")
    return inner2

def wrapper_3(func3):
    def inner3():
        print("装饰器~~~3333")
        func3()
    return inner3

@wrapper_1   #func1 = show[show---->inner2]   show = inner1
@wrapper_2   #func2 = show[show---->inner3]  show = inner2
@wrapper_3   #func3=show   show = inner3
def show():
    print("showing")
show()
"""
装饰器~~~1111
装饰器~~~3333
showing
装饰器~~~2222

def wrapper_1(func1):
    def inner1():
        func1()
        print("装饰器~~~1111")
    return inner1

def wrapper_2(func2):
    def inner2():
        func2()
        print("装饰器~~~2222")
    return inner2

def wrapper_3(func3):
    def inner3():
        print("装饰器~~~3333")
        func3()
    return inner3

@wrapper_1
@wrapper_3
@wrapper_2
def show():
    print("showing")
show()
"""
装饰器~~~3333
showing
装饰器~~~2222
装饰器~~~1111
"""

"""
总结:
    a。当多个装饰器修饰同一个函数时,采用的就近原则,从下往上进行传参【一直改变原函数的指向】,从上往下执行
    b.原函数都只会被执行一次
    c.通过不断修改原函数的指向完成整个装饰器的调用过程
"""

高阶函数

一个函数的参数为另外一个函数,返回一个结果,该函数被称为高阶函数
1、map映射

#map的用法
"""
map(fn,Iterable1,Iterable2.....)
    fn:函数【def 和 lambda】
    Iterable:可迭代对象

功能:根据fn中的逻辑,依次作用域序列中的每一个元素,最终返回一个新的序列
"""
# 1、
list1 = [1,2,3,4,5]

result = map(str,list1)
print(list(result))


def add(x,y):
    return x + y


result1 = map(add,[1,2,3],[4,5,6])
print(list(result1))

'''
注意:
	  1、map中的序列有几个,函数的参数一般设置几个【一一对应】
	  2、map中的函数一般要设置返回值,否则生成的元素全部是None【将结果保存在一个新容器中】
	  3、多个序列的长度可以不一致,以元素少的序列作为参照
''' 
# 练习:

list1 = ["faf","Hello","AAA"]
newlist1 = [ch.upper() for ch in list1]
print(newlist1)
result = list(map(lambda ch:ch.upper(),list1))
print(result)

from functools import reduce

"""
reduce(fn,Iterable)

功能:使用fn首先将Iterable中的第0个和第一个元素进行运算,将得到的结果和第2个元素进行运算
知道Iterable中的元素全部参与运算

举例:



"""
# 需求:求一个列表中国所有元素的和
list1 = [1,2,3,4,5]
# 方式一
total = 0
for num in list1:
    total += num
print(total)

# 方式二:


def add(a, b):
    return a + b


result = reduce(add, list1)
print(result)

# 练习3:将[2,4,6,8]转换成整数2468


def ssr(x,y):
    return str(x) + str(y)


result1 = reduce(ssr, [2,4,6,8])
print(int(result1), type(result1))

# 1
def check(x,y):
    return x * 10 + y

# 2
result2 = reduce(check, [2, 4, 6, 8])
print(result2)

# 3
result3 = reduce(lambda x, y: x * 10 + y, [2, 4, 6, 8])
print(result3)

# 4、需求:使用map和reduce实现字符串转整型的操作
# "6523" ---------> 6523

# 建立映射关系
def str_to_int(s):
    dict1 = {'0': 0, "1": 1, "2": 2, '3': 3}
    return dict1[s]

result22 = list(map(str_to_int, '3231'))
print(result22)
# 实现转换
result33 = reduce(lambda x, y:x * y +y, result22)
print(result33)

# 合起来写
result44 = reduce(lambda x, y:x *10+y,map(str_to_int,'3231'))
print(result44)

2、reduce

from functools import reduce

"""
reduce(fn,Iterable)

功能:使用fn首先将Iterable中的第0个和第一个元素进行运算,将得到的结果和第2个元素进行运算
知道Iterable中的元素全部参与运算

举例:
func(x,y)
[a,b,c,d]
reduce(func((a,b)c,d))

工作原理:
func(func(func(a,b),c),d)
"""
# 需求:求一个列表中国所有元素的和
list1 = [1,2,3,4,5]
# 方式一
total = 0
for num in list1:
    total += num
print(total)

# 方式二:


def add(a, b):
    return a + b


result = reduce(add, list1)
print(result)

# 练习3:将[2,4,6,8]转换成整数2468


def ssr(x,y):
    return str(x) + str(y)


result1 = reduce(ssr, [2,4,6,8])
print(int(result1), type(result1))

# 1
def check(x,y):
    return x * 10 + y

# 2
result2 = reduce(check, [2, 4, 6, 8])
print(result2)

# 3
result3 = reduce(lambda x, y: x * 10 + y, [2, 4, 6, 8])
print(result3)

# 4、需求:使用map和reduce实现字符串转整型的操作
# "6523" ---------> 6523

# 建立映射关系
def str_to_int(s):
    dict1 = {'0': 0, "1": 1, "2": 2, '3': 3}
    return dict1[s]

result22 = list(map(str_to_int, '3231'))
print(result22)
# 实现转换
result33 = reduce(lambda x, y:x * y +y, result22)
print(result33)

# 合起来写
result44 = reduce(lambda x, y:x *10+y,map(str_to_int,'3231'))
print(result44)

3、filter过滤

"""
filter(fn,Iterable)

功能:通过条件过滤可迭代对象
        根据函数的返回值为True或者false决定是否保留元素,True保存,F过滤

"""

# 1、过滤奇数
list1 = [1,2,3,4,5,6,7,8,9,10]
def check(num):
    if num % 2 ==0:
        return True
    else:
        return False


result1 = filter(check,list1)
print(list(result1))



# 2、需求,将其中为"无"的数据过滤掉
list2 = [["张三", 18, 100,'跳舞'], ["狗蛋儿", 15, 95,"无"], ["jack", 19, 60, "唱歌"]]

def test(ch):
    if ch == "无":
        return False
    return True

newlist = []
for sublist in list2:
    m = filter(test,sublist)
    newlist.append(list(m))
print(newlist)

4、sorted排序

# 一、sort
list1 = [3,534,54,654,28]
list_1 = ['ss','sasadasd','dsaftdsffas''sdfs']
# 升序
list1.sort()
print(list1)               # [3, 28, 54, 534, 654]
# 降序
list1.sort(reverse=True)
print(list1)                # [654, 534, 54, 28, 3]
# 自定义排序
list_1.sort(key=len)
print(list_1)                # ['ss', 'sasadasd', 'dsaftdsffassdfs']


# 二、sorted
list1 = [3,534,54,654,28]
list_1 = ['ss','sasadasd','dsaftdsffas''sdfs']
list2 = sorted(list1)             
print(list1)                       # [3, 534, 54, 654, 28]
print(list2)                       # [3, 28, 54, 534, 654]

list3 = sorted(list1,reverse=True)
print(list1)                      # [3, 534, 54, 654, 28]
print(list3)                      # [654, 534, 54, 28, 3]

list4 = sorted(list_1,key=len,reverse=True)
print(list4)                    # ['dsaftdsffassdfs', 'sasadasd', 'ss']


递归函数

1、概念
a、递归函数:一个函数调用自身,该函数被称为递归函数
b、递归调用:整个代码执行的过程被称为递归调用
c、递归包含了一种隐式的循环,它就会重复某段代码,但是这种循环不需要条件进行控制
d、需要解决的问题:再合适的实际让隐式的循环停止下来
e、使用递归解决问题的思路:
1、找到一个临界值【能让递归停止下来】
2、找到两次循环的关系

# 斐波那契数列
"""
1 2 3 4 5 6  7 8   9 10 11 12  13……
1 1 2 3 5 8 13 21 34 55 89 144……

规律:
    a、第一个位置和第二个位置上的数是固定的,都是1------->临界值【条件】
    b、第n个位置上的数 = (n-1) + (n-2)

分析:
func(3) = func(2) + func(1)    ------>1 + 1 = 2

func(5) = func(4) + fun(3)
        = func(3) + func(2) +func(2) + func(1)
        = func(2)+func(1)+ func(2) + func(2) +fun(1)
"""

count = 0


def func(n):
    global count
    count += 1
    if n == 1 or n == 2:
        return 1
    else:
        return func(n-1) + func(n-2)


print(func(10))     # 55
print('执行的次数:',count)   # 109

# 注意:递归中必须要有返回值,因为下一次运算中,一般要用到上一次的结果
# 练习:使用递归求1~某个数之间所有整数的和:


def get_total(num):
    if num == 1:
        return 1
    else:
        return get_total(num - 1) + num


print(get_total(100))          # 5050
    
"""
分析:
gettotal(10) = gettotal(9) + 10
get....9     = get.....8   + 9
....
gettotal(1)   = 1 -------临界值
"""

"""
总结:
    优点:代码实现简单
    缺点:过深的递归可能会造成栈溢出
    建议:没事少装逼,慎用
"""

栈和队列

【面试题:栈和队列的区别和联系】

栈:Stack,是限定在表的一端进行插入和删除操作的线性表【抽象成一个开口向上的容器】

队列:Queue,是限定在表的一端进行插入操作,在表的另外一端进行删除操作的线性表【抽象成一个水平放置的水管】

线性表:属于一种线性结构【容器】,可以包含有限的序列节点,其中插入数据和删除数据都有一定的规律

相同点:

a.都是线性表

b.二者的插入操作都是表尾进行的

c.二者都可以通过顺序结构和链式结构实现

d.二者在实现插入和删除操作时,时间复杂度和空间复杂度是相同的【工作效率相同】

不同点:

a.删除的位置不同:栈的删除在表尾进行,队列的删除在表头进行

b.使用场景不同:

	栈:Python中的基本语法【表达式的求值和转换,函数的定义和调用】

	队列:计算机中各种资源的分配【系统】

c.工作原理不同:

	栈:先进后出,后进先出

	队列:先进先出,后进后出

stack = []
print(stack)

#入栈【向栈中添加数据】:append
stack.append(11)
print(stack)
stack.append(22)
print(stack)
stack.append(33)
print(stack)
stack.append(44)
print(stack)

#出栈【从栈中删除数据】:pop
stack.pop()
print(stack)
stack.pop()
print(stack)
stack.pop()
print(stack)
stack.pop()
print(stack)

队列

from collections import deque

queue = deque()
print(queue)

#入队【向队列中添加数据】:append
queue.append(11)
print(queue)
queue.append(22)
print(queue)
queue.append(33)
print(queue)
queue.append(44)
print(queue)

#出队【从队列中删除数据】;popleft/pop
queue.popleft()
print(queue)
queue.popleft()
print(queue)
queue.popleft()
print(queue)
queue.popleft()
print(queue)

遍历目录

import os


path = r"C:\Program Files (x86)"

# 1、listdir 列出指定目录下所有的内容【文件或者文件夹】,返回一个列表,列表中的元素为文件或者文件夹名称

list1 = os.listdir(path)
print(list1)

# 2、join根据父路径和当前文件夹的名称给拼接路径

path1 = path + "\\" + "Google"
print(path1)

path2 = os.path.join(path,"Google")
print(path2)


# 3、isfile/isdir: 判断指定的路径是否是文件或者文件夹

result = os.path.isfile(path2)
print(result)

result = os.path.isdir(path2)
print(result)

递归遍历目录
import os


def get_file(path):
    if os.path.isfile(path):
        print("文件",path)
        return

    # 说明path是一个文件夹
    file_list = os.listdir(path)

    # 遍历列表,凭借每个完整的路径
    for file_name in file_list:
        # 拼接
        file_path = os.path.join(path,file_name)

        if os.path.isdir(file_path):
            print("目录",file_path)

            # 使用递归
            get_file(file_path)
        else:
            print("文件",file_path)


if __name__ == "__main__":
    path = r"E:\eclipse_PHP"
    get_file(path)
 
使用递归遍历目录
import os

# 使用栈遍历


# 思路:如果路径是目录,则添加到栈中,如果是文件,则直接打印

def get_file(path):
    # 定义一个空栈
    stack = []

    if os.path.isfile(path):
        print("文件:",path)
        return

    # 将path添加到栈中
    stack.append(path)

    # 处理栈,是一个循环过程,循环条件:栈不为空
    while len(stack) != 0:
        dir_path = stack.pop()

        # 获取初始路径下的所有路径
        file_list = os.listdir(dir_path)

        # 遍历,拼接路径
        for file_name in file_list:
            file_path = os.path.join(dir_path,file_name)

            if os.path.isdir(file_path):
                # 如果是目录,则加到栈中
                stack.append(file_path)
            else:
                print("文件:",file_path)


if __name__ == "__main__":
    path = r"E:\eclipse_PHP"
    get_file(path)

使用队列遍历目录
#使用队列遍历
import os
from collections import deque

import os
from collections import deque


# 使用栈遍历


# 思路:如果路径是目录,则添加到栈中,如果是文件,则直接打印

def get_file(path):
    # 定义一个空栈
    queue = deque()

    if os.path.isfile(path):
        print("文件:",path)
        return

    # 将path添加到栈中
    queue.append(path)

    # 处理栈,是一个循环过程,循环条件:栈不为空
    while len(queue) != 0:
        dir_path = queue.pop()

        # 获取初始路径下的所有路径
        file_list = os.listdir(dir_path)

        # 遍历,拼接路径
        for file_name in file_list:
            file_path = os.path.join(dir_path,file_name)

            if os.path.isdir(file_path):
                # 如果是目录,则加到栈中
                queue.append(file_path)
            else:
                print("文件:",file_path)


if __name__ == "__main__":
    path = r"E:\eclipse_PHP"
    get_file(path)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值