当前位置: 首页 > wzjs >正文

怎样做app网站建设全国各城市疫情高峰感染高峰进度

怎样做app网站建设,全国各城市疫情高峰感染高峰进度,哪个软件发视频可以赚钱,wordpress主题 演示数据此 Python 代码借助闭包构建了计算对数的函数。闭包指的是一个函数与其所引用的外部变量共同构成的一个整体。借助闭包,我们能够创建具有特定行为的函数,并且这些函数可以记住其创建时的环境。 代码详细分析 导入模块 python import math 导入 math …

此 Python 代码借助闭包构建了计算对数的函数。闭包指的是一个函数与其所引用的外部变量共同构成的一个整体。借助闭包,我们能够创建具有特定行为的函数,并且这些函数可以记住其创建时的环境。

代码详细分析

导入模块

python

import math


 

导入 math 模块,它是 Python 的标准库,提供了众多数学相关的函数,这里主要使用其中的 log 函数来计算对数。

定义外层函数 logFun

python

def logFun(base):


 

这是外层函数,它接收一个参数 base,该参数代表对数的底数。

定义内层函数 inner_fun

python

def inner_fun(x):return math.log(x, base)


 

inner_fun 是定义在 logFun 内部的函数,它接收一个参数 x,代表对数的真数。math.log(x, base) 会计算以 base 为底 x 的对数。要注意的是,base 并非在 inner_fun 内部定义,而是从外部的 logFun 函数获取,这就形成了闭包。

返回内层函数

python

return inner_fun


 

logFun 函数返回 inner_fun 函数对象。这样一来,调用 logFun 时会得到一个函数,这个函数记住了 base 的值。

创建闭包实例

python

log2 = logFun(2)
log10 = logFun(10)


 

  • logFun(2) 调用 logFun 函数,传入参数 2,返回一个闭包函数。这个闭包函数会记住底数为 2,并将其赋值给 log2
  • logFun(10) 同理,传入参数 10,返回的闭包函数记住底数为 10,并赋值给 log10
断言验证结果

python

assert abs(log2(2) - 1) < 1e-8
assert abs(log10(10) - 1) < 1e-8


 

这两行代码属于断言语句,用于验证计算结果是否符合预期。下面详细解释:


 

  • log2(2):调用 log2 这个闭包函数,传入参数 2。由于 log2 记住的底数是 2,所以 log2(2) 计算的是以 2 为底 2 的对数,理论上结果为 1
  • abs(log2(2) - 1)abs 是 Python 的内置函数,用于计算绝对值。这里计算 log2(2) 的结果与 1 的差值的绝对值。
  • < 1e-81e-8 表示 1 乘以 10 的负 8 次方,也就是 0.00000001。由于浮点数在计算机中的表示存在精度问题,所以不直接判断 log2(2) 是否等于 1,而是判断它们的差值的绝对值是否小于一个极小的数 1e-8。如果小于这个数,就认为计算结果是正确的。
  • assert 语句assert 语句用于调试和验证代码。如果 assert 后面的条件为 True,程序会继续执行;如果为 False,程序会抛出 AssertionError 异常。


 

同理,assert abs(log10(10) - 1) < 1e-8 验证的是以 10 为底 10 的对数是否接近 1

代码原理剖析

  1. 装饰器函数 makeBold
    • def makeBold(fun): 定义了一个名为 makeBold 的装饰器函数,它接受一个函数 fun 作为参数 。这是装饰器的典型特征,将被装饰的函数当作参数传入。
    • 内部嵌套函数 wrapper
      • def wrapper(): 定义了内部的 wrapper 函数。在装饰器逻辑中,wrapper 函数起到包装的作用。
      • return '<b>' + fun() + '</b>' 这行代码调用传入的 fun 函数(也就是被装饰的函数),并将其返回值用 <b></b> 标签包裹起来。这里 <b> 是HTML标签,用于表示加粗显示。
      • return wrappermakeBold 函数最后返回 wrapper 函数对象。这意味着,当 makeBold 装饰某个函数时,实际上返回的是这个 wrapper 函数,后续调用被装饰函数时,执行的就是 wrapper 函数的逻辑。
  1. 被装饰函数 hello
    • @makeBold 是装饰器语法糖,等同于 hello = makeBold(hello) 。它的作用是将 makeBold 装饰器应用到 hello 函数上。
    • def hello(): 定义了 hello 函数,它原本的功能是返回字符串 'Hello world!'
  1. 函数调用
    • print hello() :在装饰器作用下,调用 hello 函数时,实际执行的是 makeBold 函数中 wrapper 函数的逻辑。wrapper 函数先调用原始的 hello 函数获取返回值 'Hello world!' ,然后将其用 <b></b> 标签包裹,最终返回 <b>Hello world!</b> 并打印输出。

装饰器总结

装饰器本质上是利用闭包特性。makeBold 函数中的 wrapper 函数记住了传入的 fun 函数(形成闭包),并且在 wrapper 函数被调用时执行额外的逻辑(这里是添加HTML加粗标签),从而在不修改原函数代码的基础上,增强了函数的功能。

首先看左边的代码,没有使用 functools.wraps。左边定义了 makeTag 装饰器,然后用 @makeTag ('p') 和 @makeTag ('b') 装饰 hello 函数。装饰器的运行过程是怎样的呢?


 

先看左边的 makeTag 函数。def makeTag (tag): 这个函数接收 tag 参数,返回 inner_decorator。inner_decorator 接收 fun 参数,返回 wrapper。wrapper 函数把 fun 的返回值用 tag 标签包裹。当使用两个装饰器时,@makeTag ('p') 和 @makeTag ('b'),相当于 hello = makeTag ('p')(makeTag ('b')(hello))。先执行 makeTag ('b')(hello),得到一个 wrapper 函数,然后再用 makeTag ('p') 装饰这个 wrapper,又得到一个新的 wrapper。这样,原来的 hello 函数就被替换成最外层的 wrapper 了。所以当打印 hello.__name__时,就会显示 wrapper,__doc__也变成 None,因为原函数的属性丢失了。


 

再看右边的代码,使用了 functools.wraps。右边的 makeTag 装饰器在 wrapper 函数上用了 @functools.wraps (fun),这会把原函数 fun 的属性复制给 wrapper。同样是 @makeTag ('p') 和 @makeTag ('b') 装饰 hello 函数,过程类似,但因为 wraps 的作用,wrapper 继承了原 hello 函数的属性。所以打印 hello.__name__时还是 hello,__doc__也能显示原来的函数说明。

图中展示了两组代码,分别演示了带参数装饰器在使用和不使用 functools.wraps 时的不同效果,以下是对两组代码中函数运行过程的详细介绍:

左侧代码(未使用 functools.wraps

  1. 定义装饰器 makeTag
    • def makeTag(tag)::定义一个接收标签参数 tag 的函数,返回内部装饰器 inner_decorator
    • def inner_decorator(fun)::接收被装饰的目标函数 fun(如 hello),返回包裹函数 wrapper
    • def wrapper(*args, **kwargs)::使用 tagfun(*args, **kwargs) 的返回值添加标签(如 <tag>... </tag>),最后返回包装后的结果。此时,wrapper 函数完全替代了原 hello 函数。
  1. 装饰与调用 hello 函数
    • @makeTag('p') @makeTag('b'):等价于 hello = makeTag('p')(makeTag('b')(hello))。先执行 makeTag('b')(hello),生成一个用 <b>...</b> 包裹的 wrapper;再执行 makeTag('p') 装饰该 wrapper,生成新的用 <p>...</p> 包裹的 wrapper。最终,hello 函数被替换为最外层的 wrapper
    • print(hello.__name__):输出 wrapper(原 hello 函数名丢失,被 wrapper 替代)。
    • print(hello.__doc__):输出 None(原 hello 的文档字符串丢失)。

右侧代码(使用 functools.wraps

  1. 定义装饰器 makeTag
    • import functools:引入模块以使用 wraps
    • def makeTag(tag)::同样接收标签参数 tag,返回 inner_decorator
    • def inner_decorator(fun)::接收目标函数 fun,但通过 @functools.wraps(fun)fun 的属性(如 __name____doc__)复制给 wrapper
    • def wrapper(*args, **kwargs)::与左侧逻辑相同,用 tag 标签包裹 fun 的返回值,但因 wraps 的作用,wrapper 继承了 fun 的属性。
  1. 装饰与调用 hello 函数
    • @makeTag('p') @makeTag('b'):同样等价于 hello = makeTag('p')(makeTag('b')(hello)),装饰过程与左侧一致,但由于 @functools.wraps(fun) 的存在:
    • print(hello.__name__):输出 hello(保留原函数名)。
    • print(hello.__doc__):输出 这里是函数说明(保留原函数文档字符串)。

总结

  • 装饰器逻辑:两组代码中,装饰器均通过多层嵌套实现标签叠加(先 b 标签,再 p 标签)。
  • 属性保留:左侧因未使用 functools.wraps,原 hello 函数属性被覆盖;右侧通过 @functools.wraps(fun) 保留了原函数属性,使 hello__name____doc__ 正常显示。


 

具体步骤:左边,装饰器替换函数后,属性丢失;右边,通过 wraps 保留属性。两个装饰器的调用顺序都是从里到外,先处理 @makeTag ('b'),再处理 @makeTag ('p')。每个装饰器都会生成一个 wrapper,左边的 wrapper 没有保留原函数属性,右边的保留了。

记录调用时间,不改变现有代码,用装饰器打印日志,记录时间。

http://www.dtcms.com/wzjs/491684.html

相关文章:

  • 佛山从事网站建设seo管理平台
  • 浏览器网站网址大全广州抖音推广公司
  • 网站建设的活怎么接seo排名优化软件有
  • 日本设计类网站seowhy官网
  • 网站banner图设计成多少合适优化资讯
  • 腾云公司做网站bt磁力天堂torrentkitty
  • 湘潭高端网站建设山东今日头条新闻
  • 网站策划方案800字品牌营销策略
  • 2022电商平台排行榜宁波seo网络推广推荐
  • 深圳网站建设与网站制作天津推广的平台
  • 怎么样在网站做产品推广青岛官网seo
  • 手机 网站 系统关键词推广优化app
  • html 企业网站模板广州网站优化运营
  • 本地网站做不大公司推广策划
  • 昆明 网站 制作新品上市的营销方案
  • 中国十大小说网站排名淄博seo公司
  • 做网站时新闻的背景图小红书推广平台
  • wordpress添加dplayer灰色词seo推广
  • 网页设计素材收集seo推广优化方案
  • 东莞建设网站培训免费网站alexa排名查询
  • 网站如何做seo优化十大永久免费的软件下载
  • 网站优化标签企业官网推广
  • 网站建设与管理方案书王通seo教程
  • 卡通画风的网站乐云seo
  • 怎么用h5做网站怎么在百度上做推广上首页
  • 城市建设模拟游戏网站中文注解网络广告设计
  • 开发一个商城网站多少钱网站排名查询alexa
  • 创新的购物网站建设优化大师优化项目有哪些
  • 温州快速网站建设排名电商网站开发需要多少钱
  • 中国没公司怎么做网站郑州seo使用教程