鱼C论坛

 找回密码
 立即注册
查看: 1646|回复: 4

[已解决]新手python问题

[复制链接]
发表于 2023-7-29 21:17:48 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
问题如下:
1.如下代码中为什么不能不用call_func嵌套函数而是只用一层函数?
2.print(f"一共耗费了{(stop - start):.4f}秒。")这个代码中的 : 和 .4f 是什么用法?
3.@time_master的作用是什么?好像删去也不影响?不是很理解装饰器的本质。


代码如下:
import time

def time_master(func):
    def call_func():
        print("开始运行程序")
        start = time.time()
        func()
        stop = time.time()
        print("结束运行程序")
        print(f"一共耗费了{(stop - start):.4f}秒。")
    return call_func

@time_master
def myfunc():
    time.sleep(2)
    print("I love Orig.")

myfunc()
最佳答案
2023-7-30 02:28:48
3
装饰器实际上算是python中的一种语法糖
def outer(func):
    def inter():
        print(1)
        func()
        print(2)
    retuen inter
   
#########
@outer
def func():
    pass

等效于

def func():
    pass
func=outer(func)


##########

实际上这@outer相当于执行了func=outer(func)
也就是说此时的func已经是嵌套内层函数inter
若删去@outer则不执行func=outer(func)
func便还是原来的样子并未得到装饰


1
这里不能用一层函数代替
这里使用嵌套函数构成闭包,以便将装饰好的内层函数返回,构成装饰器

2
这是一种格式化输出字符串的语法
{表达式 : 格式说明符}
这里的 : 是表达式和格式说明符的分界线(也许可以这么说)
这里的 . 后接数字 代表小数精度(保留小数点后几位)
这里的 f 代表以浮点数的格式输出

这是我的一点个人见解,若有错误的地方请指出
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-7-29 21:18:02 | 显示全部楼层
1. 使用嵌套函数call_func的目的是为了在执行函数myfunc之前和之后打印额外的信息,即"开始运行程序"和"结束运行程序"。如果只使用一层函数,无法在函数执行前后插入额外的代码。

2. :用于格式化字符串中的表达式部分,在这里表示将要格式化的内容的起始位置。.4f是对浮点数进行格式化的规范,其中.4表示保留小数点后四位。

3. @time_master是一个装饰器。装饰器可以用于修改或增强函数的功能。在这个例子中,装饰器@time_master将会把myfunc函数作为参数传递给time_master函数,并返回一个新的函数call_func,替换原本的myfunc函数。这样,每次调用myfunc时,实际上是调用了经过装饰器修饰后的call_func函数,从而在函数执行前后打印额外的信息并计算运行时间。删除@time_master装饰器会导致失去这些额外的功能。装饰器的本质是通过包装函数来修改其行为,以增加或修改其功能而不改变原始函数的定义。
如果问题已经解决,请设置最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-29 21:18:10 | 显示全部楼层
问题1:如下代码中为什么不能不用call_func嵌套函数而是只用一层函数?

答案1:在这段代码中,call_func是一个内部函数,它被用作装饰器函数time_master的一部分。装饰器是Python中的一个特殊语法,用于在函数定义时对其进行修饰或扩展。

在这里,time_master装饰器将传入的函数func进行了修饰。具体来说,它添加了计时功能,记录了函数运行的起始时间和结束时间,并输出函数执行所花费的时间。

如果不使用call_func嵌套函数,而是只用一层函数,那么装饰器功能就无法实现。在装饰器内部,我们需要定义一个新的函数(call_func)来包装原函数(func),以便添加额外的功能。如果只用一层函数,那么我们将无法在不修改原函数的情况下添加新的功能,例如计时功能。

问题2:print(f"一共耗费了{(stop - start):.4f}秒。")这个代码中的 : 和 .4f 是什么用法?

答案2:在这段代码中,print语句中的"{(stop - start):.4f}"是一个格式化字符串(formatted string)。其中的冒号(:)和 .4f 是用于格式化输出的部分。

· 冒号(:):冒号用于指定格式说明符。它告诉Python在此处插入一个值,并按照指定的格式进行显示。
· .4f:这是格式说明符的一种,表示要插入一个浮点数,并且要显示小数点后四位小数。

在这段代码中,{(stop - start):.4f} 将计算的时间差(stop - start)插入到字符串中,并按照浮点数格式显示,保留小数点后四位小数。这样就能以更友好的方式输出函数执行所耗费的时间。

问题3:@time_master的作用是什么?好像删去也不影响?不是很理解装饰器的本质。

答案3:@time_master是一个装饰器,它的作用是将装饰器下面的函数(这里是myfunc函数)传递给time_master函数,并用time_master函数返回的结果替换原来的myfunc函数。也就是说,@time_master修饰了myfunc函数,相当于对myfunc函数应用了time_master装饰器。

在这个例子中,@time_master装饰器添加了计时功能。当我们调用myfunc()时,实际上是调用经过装饰后的call_func()函数。call_func函数在运行原来的myfunc函数之前记录了开始时间,然后运行原函数myfunc,最后记录结束时间并输出执行时间。

当你说删去@time_master装饰器后不影响,可能是因为这个特定的例子中myfunc函数没有其他功能,只有一个简单的延时和输出。在这种情况下,装饰器似乎没有显著的影响。然而,装饰器的真正威力在于可以轻松地对函数进行功能扩展,尤其是当函数更加复杂时。例如,可以使用装饰器来实现日志记录、权限检查、缓存等功能,而不需要修改原函数的代码。

装饰器的本质是Python语法的一种应用,它是一种函数式编程的概念。它允许我们在不改变原函数代码的情况下,通过装饰器函数对其功能进行扩展或修饰。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-29 21:18:32 | 显示全部楼层
问题回答:

问题1:为什么不能只使用一层函数而不使用call_func嵌套函数?

在给定的代码中,使用call_func函数的嵌套结构是为了实现装饰器功能。装饰器是Python中一种特殊的语法,它允许我们通过在函数定义之前加上@装饰器函数的方式,对原函数进行装饰或修饰。在这个例子中,time_master就是一个装饰器函数,它接收一个函数作为参数,并返回一个经过修饰的新函数call_func

通过使用嵌套函数,可以在调用原函数之前和之后执行额外的逻辑。在这个例子中,call_func函数在调用原函数func之前输出"开始运行程序",在调用之后输出"结束运行程序"和耗时信息。

如果我们不使用嵌套函数,而是直接在time_master函数中执行逻辑并返回func,那么就无法在调用原函数前后插入额外的逻辑,因此无法实现装饰器的功能。

问题2:print(f"一共耗费了{(stop - start):.4f}秒。")中的:.4f是什么用法?

- :符号用于格式化字符串。在这个例子中,{}内的表达式stop - start代表一个占位符,而冒号后的.4f表示要将占位符格式化为保留4位小数的浮点数。

- :.4f中的:表示格式说明符的开始,而.4f表示格式规范。格式规范中的.4f表示将浮点数格式化为包含四个小数位的字符串形式。

问题3:@time_master的作用是什么?删去似乎也不影响运行?

@time_master是一个装饰器语法,它将函数myfunc传递给time_master装饰器函数进行修饰。

装饰器的作用是在不修改被修饰函数源代码的情况下,为函数添加额外的功能或行为。在这个例子中,time_master装饰器将在调用myfunc函数之前和之后添加输出信息和计时功能。

如果删除了@time_master装饰器,那么myfunc函数将会在原有逻辑的基础上直接执行,不会添加任何额外的功能。这样做可能会导致无法得知函数的运行时间以及其他装饰器定义的行为。

通过使用装饰器,可以将额外的功能与函数分离,提高代码的可重用性和可维护性。

希望以上解答能够帮助到您,如果还有其他问题,请随时提问。

球一个最佳答案谢谢啦!这对我非常重要!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-30 02:28:48 From FishC Mobile | 显示全部楼层    本楼为最佳答案   
3
装饰器实际上算是python中的一种语法糖
def outer(func):
    def inter():
        print(1)
        func()
        print(2)
    retuen inter
   
#########
@outer
def func():
    pass

等效于

def func():
    pass
func=outer(func)


##########

实际上这@outer相当于执行了func=outer(func)
也就是说此时的func已经是嵌套内层函数inter
若删去@outer则不执行func=outer(func)
func便还是原来的样子并未得到装饰


1
这里不能用一层函数代替
这里使用嵌套函数构成闭包,以便将装饰好的内层函数返回,构成装饰器

2
这是一种格式化输出字符串的语法
{表达式 : 格式说明符}
这里的 : 是表达式和格式说明符的分界线(也许可以这么说)
这里的 . 后接数字 代表小数精度(保留小数点后几位)
这里的 f 代表以浮点数的格式输出

这是我的一点个人见解,若有错误的地方请指出
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-25 22:07

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表