返回介绍

01. Python 工具

02. Python 基础

03. Numpy

04. Scipy

05. Python 进阶

06. Matplotlib

07. 使用其他语言进行扩展

08. 面向对象编程

09. Theano 基础

10. 有趣的第三方模块

11. 有用的工具

12. Pandas

修饰符

发布于 2022-09-03 20:46:14 字数 8501 浏览 0 评论 0 收藏 0

函数是一种对象

Python 中,函数是也是一种对象。

In [1]:

def foo(x):
    print x

print(type(foo))
<type 'function'>

查看函数拥有的方法:

In [2]:

dir(foo)

Out[2]:

['__call__',
 '__class__',
 '__closure__',
 '__code__',
 '__defaults__',
 '__delattr__',
 '__dict__',
 '__doc__',
 '__format__',
 '__get__',
 '__getattribute__',
 '__globals__',
 '__hash__',
 '__init__',
 '__module__',
 '__name__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 'func_closure',
 'func_code',
 'func_defaults',
 'func_dict',
 'func_doc',
 'func_globals',
 'func_name']

在这些方法中,__call__ 是最重要的一种方法:

In [3]:

foo.__call__(42)
42

相当于:

In [4]:

foo(42)
42

因为函数是对象,所以函数可以作为参数传入另一个函数:

In [5]:

def bar(f, x):
    x += 1
    f(x)

In [6]:

bar(foo, 4)
5

修饰符

修饰符是这样的一种函数,它接受一个函数作为输入,通常输出也是一个函数:

In [7]:

def dec(f):
    print 'I am decorating function', id(f)
    return f

len 函数作为参数传入这个修饰符函数:

In [8]:

declen = dec(len)
I am decorating function 33716168

使用这个新生成的函数:

In [9]:

declen([10,20,30])

Out[9]:

3

上面的例子中,我们仅仅返回了函数的本身,也可以利用这个函数生成一个新的函数,看一个新的例子:

In [10]:

def loud(f):
    def new_func(*args, **kw):
        print 'calling with', args, kw
        rtn = f(*args, **kw)
        print 'return value is', rtn
        return rtn
    return new_func

In [11]:

loudlen = loud(len)

In [12]:

loudlen([10, 20, 30])
calling with ([10, 20, 30],) {}
return value is 3

Out[12]:

3

用 @ 来使用修饰符

Python 使用 @ 符号来将某个函数替换为修饰符之后的函数:

例如这个函数:

In [13]:

def foo(x):
    print x

foo = dec(foo)
I am decorating function 64021672

可以替换为:

In [14]:

@dec
def foo(x):
    print x
I am decorating function 64021112

事实上,如果修饰符返回的是一个函数,那么可以链式的使用修饰符:

@dec1
@dec2
def foo(x):
    print x

使用修饰符 loud 来定义这个函数:

In [15]:

@loud
def foo(x):
    print x

In [16]:

foo(42)
calling with (42,) {}
42
return value is None

例子

定义两个修饰器函数,一个将原来的函数值加一,另一个乘二:

In [17]:

def plus_one(f):
    def new_func(x):
        return f(x) + 1
    return new_func

def times_two(f):
    def new_func(x):
        return f(x) * 2
    return new_func

定义函数,先乘二再加一:

In [18]:

@plus_one
@times_two
def foo(x):
    return int(x)

In [19]:

foo(13)

Out[19]:

27

修饰器工厂

decorators factories 是返回修饰器的函数,例如:

In [20]:

def super_dec(x, y, z):
    def dec(f):
        def new_func(*args, **kw):
            print x + y + z
            return f(*args, **kw)
        return new_func
    return dec

它的作用在于产生一个可以接受参数的修饰器,例如我们想将 loud 输出的内容写入一个文件去,可以这样做:

In [21]:

def super_loud(filename):
    fp = open(filename, 'w')
    def loud(f):
        def new_func(*args, **kw):
            fp.write('calling with' + str(args) + str(kw))
            # 确保内容被写入
            fp.flush()
            fp.close()
            rtn = f(*args, **kw)
            return rtn
        return new_func
    return loud

可以这样使用这个修饰器工厂:

In [22]:

@super_loud('test.txt')
def foo(x):
    print x

调用 foo 就会在文件中写入内容:

In [23]:

foo(12)
12

查看文件内容:

In [24]:

with open('test.txt') as fp:
    print fp.read()
calling with(12,){}

In [25]:

import os
os.remove('test.txt')

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文