python中的修饰符@的作用

1.一层修饰符

1)简单版,编译即实现

在一个函数上面添加修饰符 @另一个函数名 的作用是将这个修饰符下面的函数作为该修饰符函数的参数传入,作用可以有比如你想要在函数前面添加记录时间的代码,这样每个函数调用时就能够知道是什么时候调用的,但是你不想手动地去给每个函数添加,那么就能够使用该修饰符实现这样的功能,下面举例说明:

#coding=UTF-8
import time

def showTime(fn):
    print(‘calling time : ‘, time.time())
    fn() #调用传入的参数

@showTime
def function1():
    print(‘running function1 ‘)

@showTime
def function2():
    print(‘running function2 ‘)

返回:

calling time :  1567076890.053299
running function1
calling time :  1567076890.0533462
running function2 

但是发现showTime()函数这样子写,即使将fn()行调用代码删除,也会在编译时就输出时间信息:

import  time
def showTime(fn):
    print(‘calling time : ‘, time.time())

@showTime
def function1():
    print(‘running function1 ‘)

@showTime
def function2():
    print(‘running function2 ‘)

返回:

calling time :  1567077493.420067
calling time :  1567077493.420131

而且这个时候如果调用function1()会报错:

TypeError: ‘NoneType‘ object is not callable

2)调用才实现

如果去希望是在显示调用function1()和function2()函数时才显示时间,正确的写法是:

import time

def showTime(fn):
    def getTime():
        print(‘calling time : ‘, time.time())
        fn() #要在修饰符函数中调用传入的函数参数fn,否则function1/function2是不会被调用的,仅仅只输出了时间信息
    return getTime

@showTime
def function1():
    print(‘running function1 ‘)

@showTime
def function2():
    print(‘running function2 ‘)

function1()
function2()

返回:

calling time :  1567077669.2308512
running function1
calling time :  1567077669.230927
running function2 

3)传入参数

如果函数中需要传入参数:

def showTime(fn):
    def getTime(*args):#*args获得fn的参数
        print(‘args is : ‘, args) #查看传入的参数
        print(‘calling time : ‘, time.time())
        if len(args) > 0:
            fn(args[0]) #要在修饰符函数中调用传入的函数参数fn,否则function1/function2是不会被调用的,仅仅只输出了时间信息
        else:
            fn()
    return getTime

@showTime
def function1(a):
    print(‘running function1 ‘)
    print(‘a = ‘, a)

@showTime
def function2():
    print(‘running function2 ‘)

function1(3)
function2()

返回:

args is :  (3,)
calling time :  1567077936.79216
running function1
a =  3
args is :  ()
calling time :  1567077936.792191
running function2 

如果想要对传入的参数进行操作:

import time

def showTime(fn):
    def getTime(*args):#*args获得fn的参数
        print(‘args is : ‘, args) #查看传入的参数
        print(‘calling time : ‘, time.time())
        if len(args) > 0:
            n = args[0]
            n *= 2
            fn(n) #要在修饰符函数中调用传入的函数参数fn,否则function1/function2是不会被调用的,仅仅只输出了时间信息
        else:
            fn()
    return getTime

@showTime
def function1(a):
    print(‘running function1 ‘)
    print(‘a = ‘, a)

@showTime
def function2():
    print(‘running function2 ‘)

function1(3)
function2()

返回:

args is :  (3,)
calling time :  1567078015.031965
running function1
a =  6
args is :  ()
calling time :  1567078015.0320058
running function2 

2.如果是双重修饰符

1)简单版本,编译即实现

import time
def sayHello(fn):
    print(‘Hello‘)

def showTime(fn):
    print(‘calling time : ‘, time.time())
    fn(3)

@sayHello
@showTime
def function1(a):
    print(‘running function1 ‘)
    print(‘a = ‘, a)

这个编译就会返回:

calling time :  1567078623.5239282
running function1
a =  3
Hello

2)调用才实现

如果想要以sayHello -> showTime -> function1的顺序,写法就要变为:

#coding:utf-8import time

def sayHello(fn):
    def hello(*args):
        print(‘Hello‘)
        fn(*args) # 2
    return hello # 1

def showTime(fn):
    def getTime(*args):#4  *args获得fn的参数
        print(‘args is : ‘, args) #查看传入的参数
        print(‘calling time : ‘, time.time())
        if len(args) > 0:
            n = args[0]
            n *= 2
            fn(n) #5  要在修饰符函数中调用传入的函数参数fn,否则function1/function2是不会被调用的,仅仅只输出了时间信息
        else:
            fn()

    return getTime # 3

@sayHello
@showTime
def function1(a): # 5
    print(‘running function1 ‘)
    print(‘a = ‘, a)

function1(3)

等于sayHello(showTime(function1(a))),所以调用function1(3)时运行的顺序为 :

  • 先调用sayHello()返回的hello(3),此时传入的参数*args为(3,),然后调用hello中的fn(*args)
  • 其实就是调用showTime()返回的getTime(3),此时传入的参数*args为(3,),然后调用getTime中的fn(n=6)
  • 其实就是调用function1(6),就结束了

返回:

Hello
args is :  (3,)
calling time :  1567078847.98264
running function1
a =  6

原文地址:https://www.cnblogs.com/wanghui-garcia/p/11431662.html

时间: 2024-08-04 14:43:56

python中的修饰符@的作用的相关文章

python中的 @ 修饰符

今天学习廖老师的python教程,碰到了修饰符'@',不太了解,查看了下官方文档. 简单的整理下: @dec2 @dec1 def func(arg1, arg2, ...): pass 等价于 def func(arg1, arg2, ...): pass func = dec2(dec1(func)) 使用示例: 在comp.lang.python 和 python-dev的大部分讨论集中在更简捷地使用内置修饰符staticmethod() 和 classmethod() 上.但修饰符的功能

Java中的修饰符及其作用

修饰符类型 修饰符 说明 访问控制修饰符 default default (即缺省,什么也不写): 在同一包内可见,不使用任何修饰符.使用对象:类.接口.变量.方法. private private : 在同一类内可见.使用对象:变量.方法.   注意:不能修饰类(外部类) public public : 对所有类可见.使用对象:类.接口.变量.方法 protected protected : 对同一包内的类和所有子类可见.使用对象:变量.方法. 注意:不能修饰类(外部类). 非访问修饰符 st

java学习笔记(三)java中的修饰符abstract、static与final

一.四种访问级别的访问范围 访问级别 访问修饰符 同类 同包 子类 不同的包 公开 public 受保护 protected 默认 没有访问修饰符 私有的 private 二.使用abstract修饰符需要遵守的语法规则 1.抽象类中可以没有抽象方法,但是包含抽象方法的类必须定义为抽象类,即用abstract修饰: 2.抽象类跟抽象方法不能被final修饰符修饰: 3.抽象类中可以有非抽象方法,因为继承抽象类的子类必须重写父类中所有的抽象方法,因此抽象类中不能有抽象构造方法和抽象静态方法: 4.

java中Volatile修饰符的含义

在java语言中:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值进行对比. volatile关键字的作用就是提示vm:对于这个成员变量不能保存它的私有拷贝,而应直接与共享变量进行交互. 被volatile修饰符修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值.而且,当成员变量发生变化时,又强迫线程将变化了的值写回共享内存,这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值.这样当多个线程同时与某个

Java中的修饰符

在java中,修饰符分为访问权限修饰符和非访问权限修饰符.可以被修饰符修饰的java语言元素有类,变量,方法和接口.下面分别描述在这四个元素上使用修饰符的作用. 类 java中声明类的格式为: 访问修饰符 修饰符 class 类名 extends 父类名称 implements 接口名称{} 其中访问修饰符和修饰符可以互换位置,可以应用于类的访问修饰符为public和package,public表明类可以被任何类使用.package表示包访问权限,它是默认的访问权限,可以省略这个修饰符,使用pa

【转】C# 中访问修饰符

用通过代码:  类内部 using System;class Mod{    void defaultMethod()    {        Console.WriteLine("this is a default method");    }    public void publicMethod()    {        Console.WriteLine("this is a public method");    }    private void pr

C#中访问修饰符

范围(从小到大):private<internal/protected<protected internal<public private:只能在本类中使用internal:只能在本程序集(本项目)中使用protected:只能在具有继承关系的子类中使用(可以在不同的项目中)protected internal:在本程序集中或在不同的程序集中但是具有继承关系就可以使用public:都能使用 注意:1.如果类没有使用显示的修饰符,默认为internal,类的访问修饰符只能是public和i

Python中逗号的三种作用

最近研究python  遇到个逗号的问题 一直没弄明白 今天总算搞清楚了 1.逗号在参数传递中的使用: 这种情况不多说  没有什么不解的地方 就是形参或者实参传递的时候参数之间的逗号 例如def  abc(a,b)或者abc(1,2) 2.逗号在类型转化中的使用 主要是元组的转换 例如: >>> a=11>>> b=(a)>>> b11>>> b=(a,)>>> b(11,)>>> b=(a,22)

Java面向对象编程之Java语言中的修饰符

近日,读了孙卫琴老师的<Java面向对象编程>一书,心中颇有些感悟,想着将其记录下来. Java中的修饰符 在Java语言中,有这样一些单词(说得再准确点儿,应该是形容词):abstract(抽象的).static(静态的).public(公共的).protected(受保护的).private(私有的).synchronized(同步的).native(本地的).transient(暂时的).volatile(易失的)和final(不可改变的),它们被成为修饰符,这些修饰符可以修饰类.变量和