首页 > 代码库 > python装饰器、模块

python装饰器、模块

python装饰器

装饰器(decorator)是一种高级Python语法。装饰器可以对一个函数、方法或者类进行加工。在Python中,我们有多种方法对函数和类进行加工,比如在Python闭包中,我们见到函数对象作为某一个函数的返回结果。相对于其它方式,装饰器语法简单,代码可读性高。因此,装饰器在Python项目中有广泛的应用。

由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用函数,假设我们要增强函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator),decorator就是一个返回函数的高阶函数。

装饰器方法

  • 先定义一个简单的函数,计算平方和
# get square sum
def square_sum(a, b):
    return a**2 + b**2
print(square_sum(3, 4))

如果要为square_sum()函数添加打印功能,修改后的写法如下:
# get square sum
def square_sum(a, b):
    print("intput:", a, b)
    return a**2 + b**2

print(square_sum(3, 4)

使用装饰器实现修改:
def decorator(F):
    def new_F(a, b):
        print("input", a, b)
        return F(a, b)
    return new_F
# get square sum
@decorator
def square_sum(a, b):
    return a**2 + b**2
print(square_sum(3, 4))

def decorator(F):
    def new_F(a, b):
        print("input", a, b)
        return F(a, b)
    return new_F

# get square sum
@decorator
def square_sum(a, b):
    return a**2 + b**2

print(square_sum(3, 4))

装饰器可以用def的形式定义,如上面代码中的decorator。装饰器接收一个可调用对象作为输入参数,并返回一个新的可调用对象。装饰器新建了一个可调用对象,也就是上面的new_F。new_F中,我们增加了打印的功能,并通过调用F(a, b)来实现原有函数的功能。

定义好装饰器后,可以通过@语法使用了。在函数square_sum定义之前调用@decorator,实际上将square_sum传递给decorator,并将decorator返回的新的可调用对象赋给原来的函数名(square_sum)。 所以,当调用square_sum(3, 4)的时候,就相当于:

square_sum = decorator(square_sum)
square_sum(3, 4)

从本质上,装饰器起到的就是这样一个重新指向变量名的作用(name binding),让同一个变量名指向一个新返回的可调用对象,从而达到修改可调用对象的目的,如果有其他的类似函数,可以继续调用decorator来修饰函数,而不用重复修改函数或者增加新的封装。

含参的装饰器

装饰器调用中,比如@decorator,该装饰器默认它后面的函数是唯一的参数。装饰器的语法允许我们调用decorator时,提供其它参数,比如@decorator(a)。

# a new wrapper layer
def pre_str(pre=‘‘):
    # old decorator
    def decorator(F):
        def new_F(a, b):
            print(pre + "input", a, b)
            return F(a, b)
        return new_F
    return decorator

# get square sum
@pre_str(‘hello‘)
def square_sum(a, b):
    return a**2 + b**2
上面的pre_str是允许参数的装饰器。它实际上是对原有装饰器的一个函数封装,并返回一个装饰器。我们可以将它理解为一个含有环境参量的闭包。
当我们使用@pre_str(‘hello‘)调用的时候,Python能够发现这一层的封装,并把参数传递到装饰器的环境中。该调用相当于
square_sum = pre_str(‘hello‘) (square_sum)

python模块、包

1、import语句

 

     在Python中用关键字import来引入某个模块,比如要引用模块math,就可以在文件最开始的地方用import math来引入,语法如下:

            import module1[, module2[,... moduleN]

 

 model.py语句

 

def run():
print(‘这个是当前目录下的,这是在model里面的run函数‘)
def run1():
print(‘run1‘)
def run2():
print(‘run2..‘)
name = 5print(‘66666‘)

model2.py语句
import model
model.run1()
model.run2()
model.run()

输出:

66666
test
run1
run2..
这个是当前目录下的,这是在model里面的run函数

说明:import的本质就是把这个python文件从头到尾执行一遍

2、from…import 语句

    Python的from语句让你从模块中导入一个指定的部分到当前命名空间中,语法如下:

           from modname import name1[, name2[, ... nameN]]

 from model import run,run1
run()
run1()

输出:
66666
这个是当前目录下的,这是在model里面的run函数
run1

 

3、From…import* 语句

 

     把一个模块的所有内容全都导入到当前的命名空间也是可行的,只需使用如下声明:

from modname import *

注:从一个模块里面导入所有的函数,不建议过多使用。

4、搜索路径和路径搜索

模块的导入需要叫做“路径搜索”的过程。

搜索路径:查找一组目录

路径搜索:查找某个文件的操作

Python搜索模块的路径:
1)、程序的主目录
2)、PTYHONPATH目录(如果已经进行了设置)
3)、标准连接库目录(一般在/usr/local/lib/python2.X/)
4)、任何的.pth文件的内容(如果存在的话).新功能,允许用户把有效果的目录添加到模块搜索路径中去

ImportError: No module named myModule,这种错误就是说:模块不在搜索路径里,从而导致路径搜索失败!
解决方法:1、在调用文件中添加sys.path.append("模块文件目录");
2、使用pth文件,在 site-packages 文件中创建 .pth文件,将模块的路径写进去,一行一
个路径,以下是一个示例,pth文件也可以使用注释:
# .pth file for the  my project(这行是注释),命名为xxx.pth文件
C:\Users\Administrator\Desktop\test

5、包

     包是一种管理 Python 模块命名空间的形式,采用"点模块名称",比如一个模块的名称是 A.B, 那么他表示一个包 A中的子模块 B ,如:

         import sound.effects.echo   

    包和文件夹的区别就是包下面有个__init__.py,在python2里面,如果你要导入其他文件夹下面的python文件,那么必须是一个包

   python3不需要,只是文件夹就行了

   

  



 






 

 

 

python装饰器、模块