【每日一练】python函数与装饰器

Python装饰器是一种用于修改函数或类的行为的语法结构。装饰器可以在不修改原始函数或类的情况下,为它们添加额外的功能。

使用装饰器的常见场景是在不改变原函数代码的情况下,给函数添加日志记录、性能统计、输入验证等功能。装饰器还可以用于授权、缓存、重试等功能。

装饰器通过在函数或类定义的上面添加@语法糖来使用。当定义了一个函数或类后,可以通过在其上面添加@装饰器名称,将装饰器应用到函数或类上。

下面是一个简单的装饰器示例:

def log_decorator(func):
    def wrapper(*args, **kwargs):
        print(f"Calling function {func.__name__}")
        result = func(*args, **kwargs)
        print(f"Finished calling function {func.__name__}")
        return result
    return wrapper

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

print(add(1, 2))

输出结果为:

Calling function add
Finished calling function add
3

在上面的示例中,定义了一个装饰器log_decorator,它会在被装饰的函数调用前后打印日志。然后,通过@log_decorator将装饰器应用到add函数上。当调用add函数时,实际上是调用了log_decorator返回的wrapper函数,从而实现了打印日志的功能。

可以看到,装饰器可以方便地为函数添加额外的功能,而不需要修改原函数的代码。装饰器还可以带参数,用于传递给装饰器的函数或类。装饰器可以是函数形式的装饰器,也可以是类形式的装饰器。
使用递归实现斐波那契数列

def f(n):
    if n < 2:
        return n
    else:
        return f(n - 1) + f(n - 2)


def fl(n):
    listF = []
    for i in range(n + 1):
        listF.append(f(i))
    print(listF)


fl(10)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

然而,这段代码有一个效率上的问题,即函数 f 使用递归的方式计算斐波那契数列,这种计算方式对于较大的 n 值非常低效,因为它会重复计算很多相同的值。

一个改进的方法是使用动态规划或者记忆化递归来避免重复计算。这里是一个使用记忆化的版本:

def memoize(f):
    cache = {}
    def helper(x):
        if x not in cache:            
            cache[x] = f(x)
        return cache[x]
    return helper

@memoize
def f(n):
    if n < 2:
        return n
    else:
        return f(n-1) + f(n-2)

def fl(n):
    listF = []
    for i in range(n+1):
        listF.append(f(i))
    print(listF)

fl(10)

在这个版本中,我们添加了一个 memoize 装饰器来缓存已计算的结果,这样在递归调用时可以直接从缓存中获取结果而不需要重新计算。

请实现一个装饰器,把函数的返回值+100然后返回

def x100(func):
    def inner(a, b):
        return func(a, b) * 100

    return inner


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


print(add(1, 2))
300

请实现一个装饰器,通过一次调用使函数重复执行5次

def run5(func):
    def inner():
        for i in range(5):
            func()

    return inner


@run5
def run():
    print("hello world")


run()
hello world
hello world
hello world
hello world
hello world

请实现一个装饰器每次调用函数时,在调用函数时输出函数名字及调用函数的时间点

import datetime


def name_time(func):
    def inner():
        func()
        print(
            "函数的执行时间点:", datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        )
        print("函数名:", func.__name__)

    return inner


@name_time
def test():
    print("test函数执行。")


test()
test函数执行。
函数的执行时间点: 2024-07-12 14:39:05
函数名: test

有一个计算两个数和的方法,为其添加一个确保两个参数都是int或float类型的装饰器,保证运算不会抛异常

def check_num(func):
    def inner(n1, n2):
        if isinstance(n1, (int, float)) and isinstance(n2, (int, float)):
            return func(n1, n2)
        else:
            print("输入的参数类型有误!")

    return inner


@check_num
def add(n1, n2):
    return n1 + n2


add(3 ** (1 / 2), 3)
4.732050807568877

有一个一次性录入人名并返回人名的方法(人名只考虑存英文),为其添加一个装饰器,使得处理后人名首字母一定大写

# 首字母大写
def upper_name(func):
    def wrapper():
        name = func()
        return name.title()

    return wrapper


@upper_name
def get_name():
    name = input("name: ")  # owen
    return name


print(get_name())
Owen

使用函数传参的方式实现去哪里旅游的功能,根据意向内容决定去玩什么

def xuzhou():
    print("去徐州了。")


def lianyungang():
    print("去连云港了。")


def shanghai():
    print("去上海了。")


def trip(city):
    print("计划去旅游")
    city()
    print("旅游结束")


attraction = input("请输入要去的景点:")
if attraction == "云龙山" or attraction == "云龙湖":
    trip(xuzhou)
elif attraction == "花果山" or attraction == "水帘洞":
    trip(lianyungang)
elif attraction == "东方明珠" or attraction == "上海迪士尼":
    trip(shanghai)
else:
    print("没有这个景点。")
计划去旅游
去连云港了。
旅游结束

相关推荐

  1. 每日python函数装饰

    2024-07-14 17:32:02       29 阅读
  2. 每日 - IGMP协议查询选举机制

    2024-07-14 17:32:02       28 阅读
  3. python函数装饰基础

    2024-07-14 17:32:02       60 阅读
  4. Python装饰管理类和函数

    2024-07-14 17:32:02       67 阅读
  5. Python高级函数技术:闭包、装饰回调

    2024-07-14 17:32:02       24 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-14 17:32:02       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-14 17:32:02       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-14 17:32:02       58 阅读
  4. Python语言-面向对象

    2024-07-14 17:32:02       69 阅读

热门阅读

  1. 27 设备流转使用心得 三

    2024-07-14 17:32:02       26 阅读
  2. 删除矩阵中0所在行 matlab

    2024-07-14 17:32:02       21 阅读
  3. 英文论文审稿2

    2024-07-14 17:32:02       22 阅读
  4. 半导体行业术语Part01

    2024-07-14 17:32:02       27 阅读
  5. go语言 中 new能初始化哪些类型?

    2024-07-14 17:32:02       18 阅读
  6. 深度学习早停(early stop)训练策略

    2024-07-14 17:32:02       20 阅读
  7. 昇思训练营打卡第二十五天(RNN实现情感分类)

    2024-07-14 17:32:02       17 阅读
  8. 使用Scikit-Learn决策树:分类问题解决方案指南

    2024-07-14 17:32:02       13 阅读
  9. return promise 为undefined原因

    2024-07-14 17:32:02       18 阅读