python装饰器详解!

Python基础篇(十一):装饰器 装饰器是Python中一种强大的函数或类修饰机制,用于在不修改原始函数或类代码的情况下,对其进行功能扩展或修改。装饰器基于函数式编程的概念,通过将函数作为参数传递给另一个函数,并返回一个新的函数来实现。装饰器是一个函数,它接受一个函数作为输入,并返回一个新的函数作为输出。装饰器可以在不修改原始函数的情况下,为其添加额外的功能或修改其行为。(感觉像java中的面向切面编程~) 阅读详情

Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里。

为什么需要装饰器

我们假设你的程序实现了say_hello()和say_goodbye()两个函数。

def say_hello():
    print "hello!"
    
def say_goodbye():
    print "hello!"  # bug here

if __name__ == '__main__':
    say_hello()
    say_goodbye()

但是在实际调用中,我们发现程序出错了,上面的代码打印了两个hello。经过调试你发现是say_goodbye()出错了。老板要求调用每个方法前都要记录进入函数的名称,比如这样:

[DEBUG]: Enter say_hello()
Hello!
[DEBUG]: Enter say_goodbye()
Goodbye!

好,小A是个毕业生,他是这样实现的。

def say_hello():
    print "[DEBUG]: enter say_hello()"
    print "hello!"

def say_goodbye():
    print "[DEBUG]: enter say_goodbye()"
    print "hello!"

if __name__ == '__main__':
    say_hello()
    say_goodbye()

很low吧? 嗯是的。小B工作有一段时间了,他告诉小A可以这样写。

def debug():
    import inspect
    caller_name = inspect.stack()[1][3]
    print "[DEBUG]: enter {}()".format(caller_name)   

def say_hello():
    debug()
    print "hello!"

def say_goodbye():
    debug()
    print "goodbye!"

if __name__ == '__main__':
    say_hello()
    say_goodbye()

是不是好一点?那当然,但是每个业务函数里都要调用一下debug()函数,是不是很难受?万一老板说say相关的函数不用debug,do相关的才需要呢?

那么装饰器这时候应该登场了。

装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。

概括的讲,装饰器的作用就是为已经存在的函数或对象添加额外的功能。

怎么写一个装饰器

在早些时候 (Python Version < 2.4,2004年以前),为一个函数添加额外功能的写法是这样的。

def debug(func):
    def wrapper():
        print "[DEBUG]: enter {}()".format(func.__name__)
        return func()
    return wrapper

def say_hello():
    print "hello!"

say_hello = debug(say_hello)  # 添加功能并保持原函数名不变

上面的debug函数其实已经是一个装饰器了,它对原函数做了包装并返回了另外一个函数,额外添加了一些功能。因为这样写实在不太优雅,在后面版本的Python中支持了@语法糖,下面代码等同于早期的写法。

def debug(func):
    def wrapper():
        print "[DEBUG]: enter {}()".format(func.__name__)
        return func()
    return wrapper

@debug
def say_hello():
    print "hello!"

这是最简单的装饰器,但是有一个问题,如果被装饰的函数需要传入参数,那么这个装饰器就坏了。因为返回的函数并不能接受参数,你可以指定装饰器函数wrapper接受和原函数一样的参数,比如:

def debug(func):
    def wrapper(something):  # 指定一毛一样的参数
        print "[DEBUG]: enter {}()".format(func.__name__)
        return func(something)
    return wrapper  # 返回包装过函数

@debug
def say(something):
    print "hello {}!".format(something)

这样你就解决了一个问题,但又多了N个问题。因为函数有千千万,你只管你自己的函数,别人的函数参数是什么样子,鬼知道?还好Python提供了可变参数*args和关键字参数**kwargs,有了这两个参数,装饰器就可以用于任意目标函数了。

def debug(func):
    def wrapper(*args, **kwargs):  # 指定宇宙无敌参数
        print "[DEBUG]: enter {}()".format(func.__name__)
        print 'Prepare and say...',
        return func(*args, **kwargs)
    return wrapper  # 返回

@debug
def say(something):
    print "hello {}!".format(something)

至此,你已完全掌握初级的装饰器写法。

高级一点的装饰器

带参数的装饰器和类装饰器属于进阶的内容。在理解这些装饰器之前,最好对函数的闭包和装饰器的接口约定有一定了解。(参见Python的闭包)

带参数的装饰器

假设我们前文的装饰器需要完成的功能不仅仅是能在进入某个函数后打出log信息,而且还需指定log的级别,那么装饰器就会是这样的。

def logging(level):
    def wrapper(func):
        def inner_wrapper(*args, **kwargs):
            print "[{level}]: enter function {func}()".format(
                level=level,
                func=func.__name__)
            return func(*args, **kwargs)
        return inner_wrapper
    return wrapper

@logging(level='INFO')
def say(something):
    print "say {}!".format(something)

# 如果没有使用@语法,等同于
# say = logging(level='INFO')(say)

@logging(level='DEBUG')
def do(something):
    print "do {}...".format(something)

if __name__ == '__main__':
    say('hello')
    do("my work")

是不是有一些晕?你可以这么理解,当带参数的装饰器被打在某个函数上时,比如@logging(level='DEBUG'),它其实是一个函数,会马上被执行,只要这个它返回的结果是一个装饰器时,那就没问题。细细再体会一下。

基于类实现的装饰器

装饰器函数其实是这样一个接口约束,它必须接受一个callable对象作为参数,然后返回一个callable对象。在Python中一般callable对象都是函数,但也有例外。只要某个对象重载了__call__()方法,那么这个对象就是callable的。

class Test():
    def __call__(self):
        print 'call me!'

t = Test()
t()  # call me

像__call__这样前后都带下划线的方法在Python中被称为内置方法,有时候也被称为魔法方法。重载这些魔法方法一般会改变对象的内部行为。上面这个例子就让一个类对象拥有了被调用的行为。

回到装饰器上的概念上来,装饰器要求接受一个callable对象,并返回一个callable对象(不太严谨,详见后文)。那么用类来实现也是也可以的。我们可以让类的构造函数__init__()接受一个函数,然后重载__call__()并返回一个函数,也可以达到装饰器函数的效果。

class logging(object):
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print "[DEBUG]: enter function {func}()".format(
            func=self.func.__name__)
        return self.func(*args, **kwargs)
@logging
def say(something):
    print "say {}!".format(something)

带参数的类装饰器

如果需要通过类形式实现带参数的装饰器,那么会比前面的例子稍微复杂一点。那么在构造函数里接受的就不是一个函数,而是传入的参数。通过类把这些参数保存起来。然后在重载__call__方法是就需要接受一个函数并返回一个函数。

class logging(object):
    def __init__(self, level='INFO'):
        self.level = level
        
    def __call__(self, func): # 接受函数
        def wrapper(*args, **kwargs):
            print "[{level}]: enter function {func}()".format(
                level=self.level,
                func=func.__name__)
            func(*args, **kwargs)
        return wrapper  #返回函数

@logging(level='INFO')
def say(something):
    print "say {}!".format(something)

内置的装饰器

内置的装饰器和普通的装饰器原理是一样的,只不过返回的不是函数,而是类对象,所以更难理解一些。

@property

在了解这个装饰器前,你需要知道在不使用装饰器怎么写一个属性。

def getx(self):
    return self._x

def setx(self, value):
    self._x = value
    
def delx(self):
   del self._x

# create a property
x = property(getx, setx, delx, "I am doc for x property")

以上就是一个Python属性的标准写法,其实和Java挺像的,但是太罗嗦。有了@语法糖,能达到一样的效果但看起来更简单。

@property
def x(self): ...

# 等同于

def x(self): ...
x = property(x)

属性有三个装饰器:setter, getter, deleter ,都是在property()的基础上做了一些封装,因为setter和deleter是property()的第二和第三个参数,不能直接套用@语法。getter装饰器和不带getter的属性装饰器效果是一样的,估计只是为了凑数,本身没有任何存在的意义。经过@property装饰过的函数返回的不再是一个函数,而是一个property对象。

>>> property()
<property object at 0x10ff07940>

@staticmethod,@classmethod

有了@property装饰器的了解,这两个装饰器的原理是差不多的。@staticmethod返回的是一个staticmethod类对象,而@classmethod返回的是一个classmethod类对象。他们都是调用的是各自的__init__()构造函数。

class classmethod(object):
    """
    classmethod(function) -> method
    """    
    def __init__(self, function): # for @classmethod decorator
        pass
    # ...
class staticmethod(object):
    """
    staticmethod(function) -> method
    """
    def __init__(self, function): # for @staticmethod decorator
        pass
    # ...

装饰器的@语法就等同调用了这两个类的构造函数。

class Foo(object):

    @staticmethod
    def bar():
        pass
    
    # 等同于 bar = staticmethod(bar)

至此,我们上文提到的装饰器接口定义可以更加明确一些,装饰器必须接受一个callable对象,其实它并不关心你返回什么,可以是另外一个callable对象(大部分情况),也可以是其他类对象,比如property。

装饰器里的那些坑

装饰器可以让你代码更加优雅,减少重复,但也不全是优点,也会带来一些问题。

位置错误的代码

让我们直接看示例代码。

def html_tags(tag_name):
    print 'begin outer function.'
    def wrapper_(func):
        print "begin of inner wrapper function."
        def wrapper(*args, **kwargs):
            content = func(*args, **kwargs)
            print "<{tag}>{content}</{tag}>".format(tag=tag_name, content=content)
        print 'end of inner wrapper function.'
        return wrapper
    print 'end of outer function'
    return wrapper_

@html_tags('b')
def hello(name='Toby'):
    return 'Hello {}!'.format(name)

hello()
hello()

在装饰器中我在各个可能的位置都加上了print语句,用于记录被调用的情况。你知道他们最后打印出来的顺序吗?如果你心里没底,那么最好不要在装饰器函数之外添加逻辑功能,否则这个装饰器就不受你控制了。以下是输出结果:

begin outer function.
end of outer function
begin of inner wrapper function.
end of inner wrapper function.
<b>Hello Toby!</b>
<b>Hello Toby!</b>

错误的函数签名和文档

装饰器装饰过的函数看上去名字没变,其实已经变了。

def logging(func):
    def wrapper(*args, **kwargs):
        """print log before a function."""
        print "[DEBUG] {}: enter {}()".format(datetime.now(), func.__name__)
        return func(*args, **kwargs)
    return wrapper

@logging
def say(something):
    """say something"""
    print "say {}!".format(something)

print say.__name__  # wrapper

为什么会这样呢?只要你想想装饰器的语法糖@代替的东西就明白了。@等同于这样的写法。

say = logging(say)

logging其实返回的函数名字刚好是wrapper,那么上面的这个语句刚好就是把这个结果赋值给say,say的__name__自然也就是wrapper了,不仅仅是name,其他属性也都是来自wrapper,比如doc,source等等。

使用标准库里的functools.wraps,可以基本解决这个问题。

from functools import wraps

def logging(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        """print log before a function."""
        print "[DEBUG] {}: enter {}()".format(datetime.now(), func.__name__)
        return func(*args, **kwargs)
    return wrapper

@logging
def say(something):
    """say something"""
    print "say {}!".format(something)

print say.__name__  # say
print say.__doc__ # say something

看上去不错!主要问题解决了,但其实还不太完美。因为函数的签名和源码还是拿不到的。

import inspect
print inspect.getargspec(say)  # failed
print inspect.getsource(say)  # failed

如果要彻底解决这个问题可以借用第三方包,比如wrapt。后文有介绍。

不能装饰@staticmethod 或者 @classmethod

当你想把装饰器用在一个静态方法或者类方法时,不好意思,报错了。

class Car(object):
    def __init__(self, model):
        self.model = model

    @logging  # 装饰实例方法,OK
    def run(self):
        print "{} is running!".format(self.model)

    @logging  # 装饰静态方法,Failed
    @staticmethod
    def check_model_for(obj):
        if isinstance(obj, Car):
            print "The model of your car is {}".format(obj.model)
        else:
            print "{} is not a car!".format(obj)

"""
Traceback (most recent call last):
...
  File "example_4.py", line 10, in logging
    @wraps(func)
  File "C:\Python27\lib\functools.py", line 33, in update_wrapper
    setattr(wrapper, attr, getattr(wrapped, attr))
AttributeError: 'staticmethod' object has no attribute '__module__'
"""

前面已经解释了@staticmethod这个装饰器,其实它返回的并不是一个callable对象,而是一个staticmethod对象,那么它是不符合装饰器要求的(比如传入一个callable对象),你自然不能在它之上再加别的装饰器。要解决这个问题很简单,只要把你的装饰器放在@staticmethod之前就好了,因为你的装饰器返回的还是一个正常的函数,然后再加上一个@staticmethod是不会出问题的。

class Car(object):
    def __init__(self, model):
        self.model = model

    @staticmethod
    @logging  # 在@staticmethod之前装饰,OK
    def check_model_for(obj):
        pass

如何优化你的装饰器

嵌套的装饰函数不太直观,我们可以使用第三方包类改进这样的情况,让装饰器函数可读性更好。

decorator.py

decorator.py 是一个非常简单的装饰器加强包。你可以很直观的先定义包装函数wrapper(),再使用decorate(func, wrapper)方法就可以完成一个装饰器。

from decorator import decorate

def wrapper(func, *args, **kwargs):
    """print log before a function."""
    print "[DEBUG] {}: enter {}()".format(datetime.now(), func.__name__)
    return func(*args, **kwargs)

def logging(func):
    return decorate(func, wrapper)  # 用wrapper装饰func

你也可以使用它自带的@decorator装饰器来完成你的装饰器。

from decorator import decorator

@decorator
def logging(func, *args, **kwargs):
    print "[DEBUG] {}: enter {}()".format(datetime.now(), func.__name__)
    return func(*args, **kwargs)

decorator.py实现的装饰器能完整保留原函数的name,doc和args,唯一有问题的就是inspect.getsource(func)返回的还是装饰器的源代码,你需要改成inspect.getsource(func.__wrapped__)。

wrapt

wrapt是一个功能非常完善的包,用于实现各种你想到或者你没想到的装饰器。使用wrapt实现的装饰器你不需要担心之前inspect中遇到的所有问题,因为它都帮你处理了,甚至inspect.getsource(func)也准确无误。

import wrapt

# without argument in decorator
@wrapt.decorator
def logging(wrapped, instance, args, kwargs):  # instance is must
    print "[DEBUG]: enter {}()".format(wrapped.__name__)
    return wrapped(*args, **kwargs)

@logging
def say(something): pass

使用wrapt你只需要定义一个装饰器函数,但是函数签名是固定的,必须是(wrapped, instance, args, kwargs),注意第二个参数instance是必须的,就算你不用它。当装饰器装饰在不同位置时它将得到不同的值,比如装饰在类实例方法时你可以拿到这个类实例。根据instance的值你能够更加灵活的调整你的装饰器。另外,args和kwargs也是固定的,注意前面没有星号。在装饰器内部调用原函数时才带星号。

如果你需要使用wrapt写一个带参数的装饰器,可以这样写。

def logging(level):
    @wrapt.decorator
    def wrapper(wrapped, instance, args, kwargs):
        print "[{}]: enter {}()".format(level, wrapped.__name__)
        return wrapped(*args, **kwargs)
    return wrapper

@logging(level="INFO")
def do(work): pass

关于wrapt的使用,建议查阅官方文档,在此不在赘述。

小结

Python的装饰器和Java的注解(Annotation)并不是同一回事,和C#中的特性(Attribute)也不一样,完全是两个概念。

装饰器的理念是对原函数、对象的加强,相当于重新封装,所以一般装饰器函数都被命名为wrapper(),意义在于包装。函数只有在被调用时才会发挥其作用。比如@logging装饰器可以在函数执行时额外输出日志,@cache装饰过的函数可以缓存计算结果等等。

而注解和特性则是对目标函数或对象添加一些属性,相当于将其分类。这些属性可以通过反射拿到,在程序运行时对不同的特性函数或对象加以干预。比如带有Setup的函数就当成准备步骤执行,或者找到所有带有TestMethod的函数依次执行等等。

至此我所了解的装饰器已经讲完,但是还有一些内容没有提到,比如装饰类的装饰器。有机会再补充。谢谢观看。

关于Python技术储备

学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后给大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

包括:Python激活码+安装包、Python web开发,Python爬虫,Python数据分析,人工智能、自动化办公等学习教程。带你从零基础系统性的学好Python!

点击领取 100%免费

👉Python所有方向的学习路线👈

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。(全套教程文末领取)

在这里插入图片描述

👉Python学习视频600合集👈

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

在这里插入图片描述

温馨提示:篇幅有限,已打包文件夹,获取方式在:文末
👉Python70个实战练手案例&源码👈

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

在这里插入图片描述

👉Python大厂面试资料👈

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

在这里插入图片描述

在这里插入图片描述

👉Python副业兼职路线&方法👈

学好 Python 不论是就业还是做副业赚钱都不错,但要学会兼职接单还是要有一个学习规划。

在这里插入图片描述

👉 这份完整版的Python全套学习资料已经上传,朋友们如果需要可以扫描下方优快云官方认证二维码或者点击链接免费领取【保证100%免费】

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/711c5966aa7348dc9340894eea54e99f.png#pic_center在这里插入图片描述

光伏发电预测(LSTM、CNN_LSTM和XGBoost回归模型,Python代码) 一旦结果与预测差距较大,可能存在光伏系统的问题,需要找出原因,然后采取适当措施来修复光伏系统并做出更好的决策。例如,根据准确的预测,光伏系统运营商可以平衡电力消耗,并将多余的电力储备用于紧急情况。然而,光伏系统的发电量估算是一个挑战,因为光伏系统的发电量受到天气条件的极大影响。整个项目文件夹(第一个文件夹为xgboost模型相关的包文件,xg.py是xgboost模型英文注释版本,xg_chinese.py是xgboost模型中文注释版本)表示空气的温度,通常以摄氏度(°C)或华氏度(°F)为单位。 阅读详情

相关推荐

【人工智能AI】是什么?

人工智能(Artificial Intelligence),英文缩写为AI。它是研究、开发用于模拟延伸和扩展人的智能的理论方法技术及应用系统的一门新的技术科学。(百度百科)人工智能的基本原理:机器从「特定的」大量数据中总结规律,形成某些「特定的知识」,然后将这种「知识」应用到现实场景中去解决实际问题。在这个基本原理的基础上,有3个特征:1、人工智能本质上是一种工具2、人工智能技能只能解决特定的问题,而不是什么都能做3、人工智能属于归纳逻辑,可以告诉你是什么,但是不能告诉你为什么。

KJCZ.AK的博客 2万+

Python学习之——装饰器

Python学习之——装饰器

selfsongs 2万+

用deepseek对GPU服务器进行压力测试

利用 DeepSeek 模型对 GPU 服务器进行压力测试,核心思路是通过,验证 GPU 服务器在计算、显存、网络等维度的承载能力,同时观察稳定性与性能瓶颈。

weixin_42795092的博客 1609

python装饰器详解

python装饰器

weixin_44992737的博客 8万+

论文阅读—Square Attack: a query-efficient black-box adversarial attack via random search

论文阅读—Square Attack: a query-efficient black-box adversarial attack via random search 发表位置 ECCV 2020 摘要 作者提出了一种基于得分的黑盒Square attack,该模型不依赖于模型的局部梯度信息,因此可以绕过梯度隐藏防御攻击。Square Attack是一种随机搜索方法,它在随机位置选择局部的方形更新,使得每次迭代时扰动近似位于可行集的边界。 背景 当涉及到对安全至关重要的机器学习应用时,对抗性的例子尤其值得

yayayamaomaoya的博客 2493

速腾R128雷达+海康全景相机ROS数据采集避坑实录:从‘雷达不转’到MATLAB标定的完整流程

本文详细记录了速腾R128激光雷达与海康威视全景相机在ROS环境下的数据采集与MATLAB标定全流程。从硬件配置的常见陷阱(如雷达旋转参数设置)、驱动编译的依赖管理,到多传感器同步的实战技巧和MATLAB标定方法,提供了完整的避坑指南和技术方案。特别针对RoboSense R128雷达和海康相机的特殊需求给出了具体解决方案。

weixin_28717807的博客 1218

python-装饰器

Python 中的装饰器是一种语法糖,可以在运行时,动态的给函数或类添加功能。装饰器本质上是一个函数,使用@ + 函数名就是可实现绑定给函数的第二个功能。将一些通用的、特定函数的功能抽象成一个装饰器,可以重复利用这些功能“装饰”代指为被装饰对象添加新的功能,“器”代指器具/工具装饰器的作用:就是在不修改被装饰对象源代码和调用方式的前提下为被装饰对象添加额外的功能。插入日志、性能测试、事务处理、缓存、权限校验函数、方法、类函数装饰器分为:无参装饰器和有参装饰,二者都是使用都是需要【

王献运的博客 2万+

从X86到ARM:全面解析服务器CPU架构的演变与未来趋势

本文深入解析了服务器CPU架构从X86到ARM的演变历程与未来趋势。文章从CISC与RISC两种设计哲学切入,分析了X86凭借生态建立的帝国地位及其面临的功耗挑战,并重点阐述了ARM架构凭借其卓越的能效比优势,正从移动端向数据中心市场发起冲击。未来,异构计算、软硬协同与专用芯片将成为服务器CPU发展的核心方向。

gold的博客 1127

Python 装饰器

Python 装饰器(Decorator)是一种用于修改或扩展函数或方法行为的工具。它允许在不改变原函数代码的情况下,动态地添加功能。装饰器本质上是一个闭包函数,接受一个函数作为参数并返回一个新的函数。

大龄程序员 6029

自动驾驶中的多传感器融合实战:用卡尔曼滤波搞定毫米波雷达与摄像头航迹对齐

本文深入探讨了自动驾驶中多传感器融合的实战技术,重点介绍了如何使用卡尔曼滤波实现毫米波雷达与摄像头的航迹对齐。通过分析传感器特性差异、时空同步挑战及工程化实现步骤,提供了包括状态向量定义、观测矩阵设计和故障检测机制在内的完整解决方案,最终实现0.15米以内的高精度航迹对齐。

weixin_28728495的博客 410

已解决“TimeouEror [WinEror 10060由于连接方在一段时间后没有正确答复 或连接的主机没有反应,连接尝试失败“,亲测有效!!!

已解决"TimeouEror [WinEror 10060由于连接方在一段时间后没有正确答复 或连接的主机没有反应,连接尝试失败",亲测有效!!!

wbajsjhhhhh的博客 1万+

详解Python的装饰器 通俗易懂的解释!

详解Python的装饰器 Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里。 为什么需要装饰器 我们假设你的程序实现了say_hello()和say_goodbye()两个函数。 def say_hello(): print “hello!” def say_goodbye(): print “hello!” # bug here if name == ‘mai...

0x8g1T9E- 3122

Sigrity Power Tree如何生成电源树操作指导

Sigrity Power Tree可以方便地生成电源树,仅需要网表文件就能将系统的电源树直观的显示出来,生成的电源树文件可以用Power DC,optimizePI进行直流和交流仿真,下面介绍如何生成电源树。Base on [Device_TYPE and VALUE]就是识别网表中器件的Device_TYPE作为power tree中的模型的名字。Allegro layout netlist file,就是从Allegro layout文件中输出的netlist第三方网表文件。如何生成电源树操作指导。

weixin_54787054的博客 1532

python装饰器详解-这是我见过最全面的Python装饰器详解!没有学不会这种说法!...

今天的任务比较繁重,因为我们要一起来学习Python中比较重要比较牛逼比较难的装饰器。我将会和大家一起通过代码的形式来迷你银行存款取款的功能,然后通过引入装饰器来一步一步优化代码。废话不多说梦开始撸代码。我们去ATM存款取款的过程用代码来表示大概如下(不大准确,仅仅是为了掩饰需要)上面是按下按钮1就存款,否则则取款。不对,存取款要输入密码啊!!!所以,我们要加密码验证代码。可以看到,虽然实现了密码...

weixin_37988176的博客 190

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

详解Python的装饰器, 看这一篇就全懂了!

1 - 简介 当我们执行某一些函数的时候, 可能会在其之前或者之后执行一些操作, 下面是一个常见的例子: import time def test (): n = 0 for i in range (10000): n += i return n t = time.time () test () spend = time.time() - t print ("it took ", spend, "s") 上面这个例子实现了一个计时器, 用来统计函数执.

qq_31269061的博客 305

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

这是我见过最全面的Python装饰器详解!没有学不会这种说法

python装饰器 刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,才有点点开始明白了。 学习python中有什么不懂的地方,小编这里推荐加小编的python学习群:895,817, 687 有任何不懂的都可以在里面交流,还有很好的视频教程pdf学习资料,大家一起学习交流! 待会我将会和大家一起通过代码的形式来迷你银行存款取款的...

weixin_42625143的博客 922

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

这是我见过最全面的Python装饰器详解!没有学不会这种说法!

上面是按下按钮1就存款,否则则取款。 不对,存取款要输入密码啊!!!所以,我们要加密码验证代码。 进群:125240963 即可获取数十套PDF哦! 可以看到,虽然实现了密码验证功能,但是代码冗余度比较高,而且现在只模拟了取款和存款功能,然而还有查询功能,转账功能等等,那么冗余度就更高了,而且相对于取款和存款函数来说,复用性没有那么高,所以我们要进...

Areigninhell的博客 220

Python异常捕获装饰器工具详解,轻松打造可靠程序!

异常捕获装饰器是 Python 中强大而灵活的工具,提供了一种优雅处理异常的方式。通过在关键函数上应用装饰器,能够捕获并处理可能发生的异常,从而增强程序的健壮性和容错性。这种装饰器在实际应用中展现了卓越的效用,特别适用于 Web 开发和数据处理等场景。在 Web 开发中,异常捕获装饰器能够确保服务器在面对请求处理过程中的异常时,提供有意义的错误信息,而不是向用户展示不友好的错误页面。这有助于改善用户体验,使系统更加可靠。

涛哥聊Python 2140

你不一定全知道的四种Python装饰器实现详解!

该程序仅供学习和娱乐,如果真的涉及重要疫情信息,请如实向上填报。 已经安装python。 需要安装selenium库。 还需要装好浏览器驱动,我用的是Win7下360极速浏览器(360Chrome)。当然也可以选用其他的更快更好的。Win10下搭建Python3.7.1 selenium3 Chrome开发环境。最后我是下载得到的驱动命名为Chromedriver.exe然后扔到了G:/360Chrome/360Chrome/Chrome/Application目录下。 fr

pythonlaodi的博客 320

python 闭包和装饰器详解_实力讲解,一文读懂Python闭包与装饰器!

什么是装饰器?装饰器(Decorator)相对简单,咱们先介绍它:“装饰器的功能是将被装饰的函数当作参数传递给与装饰器对应的函数(名称相同的函数),并返回包装后的被装饰的函数”,听起来有点绕,没关系,直接看示意图,其中 a 为与装饰器 @a 对应的函数, b 为装饰器修饰的函数,装饰器@a的作用是:简而言之:@a 就是将 b 传递给 a(),并返回新的 b = a(b)例子:上面使用@dobi来表...

weixin_39780962的博客 206
上一篇: Python 操作 MySQL 之 pysql 与 SQLAchemy!
下一篇: 几个有趣Python实例!
Python_trys
博客等级 码龄2年 4358粉丝 377原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值