Python-装饰器详解

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介:

初学python,装饰器是什么玩意儿?

1:装饰器是函数,只不过该函数可以具有特殊的含义,装饰器用来装饰函数或类,使用装饰器可以在函数执行前和执行后添加相应操作。

2:至少两层函数

方式一: 理解方式

复制代码
复制代码
def auth(func):
    def inner():
        print 'before'
        func()
    return inner
def f1():
    print 'f1'
ret = auth(f1)
f1 = ret
f1()
执行结果:

before 
f1

复制代码
复制代码

执行过程:

# 1:执行def auth(func): # 2: def f1(): # 3: ret = auth(f1) 执行auth函数,将f1传值给func, # 因为没有执行inner函数,所以return直接返回,但是返回的是inner函数名,里面的func==传入的f1 # 4: 此时 ret = innet函数名 # 5:执行f1 = ret,将inner函数名赋值给f1 # 5:执行f1(),也就是执行inner函数,然后打印before,它里面的func函数,但是func==f1,所以执行f1函数,打印f1

方式二:正常方式

复制代码
复制代码
def auth(func):
    def inner():
        print 'before'
        func()
    return inner
@auth
def f1():
    print 'f1'
f1()
复制代码
复制代码

执行过程:

# 1:使用@auth来代替注释掉的两行。 # 2:执行@auth,将下面的函数名f1作为auth的参数 # 3:执行auth函数,被装饰的函数作为参数auth(foo),auth函数的返回值,赋值给被装饰的函数的函数名@auth

方式三:在函数执行前、后分别做操作

复制代码
复制代码
def auth(func):
    def inner():
        print 'before'
        func()
        print 'after'
    return inner
@auth
def f1():
    print 'f1'
f1()
结果:
before
f1
after
复制代码
复制代码

方式四:带参数的装饰器

复制代码
复制代码
def auth(func):
    def inner(arg):
        print '验证'
        func(arg)
        print '日志'
    return inner
@auth
def f1(arg):
    print 'f1',arg
f1('带参数')
结果:
验证
f1 带参数
日志
复制代码
复制代码

方式五:含有return返回值

复制代码
复制代码
def auth(func):
    def inner(*args,**kwargs):
        print '验证'
        tmp = func(*args,**kwargs)
        print '登陆日志'
        return tmp
    return inner

@auth
def fetch_server_list():
    print 'server list'
    server_list = [1,2,3,4,5]
    return server_list

ret = fetch_server_list()
print ret

结果:
验证
server list
登陆日志
[
1, 2, 3, 4, 5]
复制代码
复制代码

方式六:多个不同类型的参数。

复制代码
复制代码
def login():
    name = 'ccc'
    if name == 'cgt':
        return True
    else:
        return False
def auth(func):
    def inner(*args,**kwargs):
        is_login = login()
        if not is_login:
            return 'invaild username'
        tmp = func(*args,**kwargs)
        print '登陆日志'
        return tmp
    return inner

@auth
def fetch_server_list():
    print 'server list'
    server_list = [1,2,3,4,5]
    return server_list

ret = fetch_server_list()
print ret
结果:
1:如果name = ccc 则输出 invaild username 2:如果name = cgt 则输出 server list 登陆日志 [1, 2, 3, 4, 5]
复制代码
复制代码

方式七:举例验证功能,使用Key值

功能函数

复制代码
复制代码
def login(key):
    local = "1234567890"
    if key  == local:
        return True
    else:
        return False
def auth(func):
    def inner(*args,**kwargs):
        key = kwargs.pop('token')                             #token是从调用函数是传参进来的        
        is_login = login(key)
        if not  is_login:
            return 'invaild username'
        tmp = func(*args,**kwargs)
        print "登陆日志"
        return tmp
    return inner
@auth
def fetch_server_list(arg):
    print 'server list'
    server_list = [1,2,3,4,5,6]
    return server_list
复制代码
复制代码

调用函数

import tmp
key = "1234567890"
#key = "12345678"
ret = tmp.fetch_server_list('text',token=key)
print ret

执行结果:1:如果两者的key相同;则正确执行结果是: server list
登陆日志
[1, 2, 3, 4, 5, 6]2:如果key不同,则输出invaild username

方式八:多装饰器

复制代码
复制代码
def w1(func):
    def inner():
        print 'before--1'
        func()
        print 'after--1'
    return inner
def w2(func):
    def inner():
        print 'before--2'
        func()
        print 'after--2'
    return inner

@w2
@w1
def f1():
    print '1111'
f1()

结果:
before
--2
before
--1 1111
after
--1
after
--2
复制代码
复制代码

递归

斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368

实现方式:

复制代码
复制代码
def func(arg1,arg2):
    if arg1 == 0:
        pass
    arg3 = arg1 + arg2
    print arg3
    func(arg2,arg3)
func(0,1)
复制代码
复制代码

如果数值大约1000,就返回这个数字

复制代码
复制代码
def func(arg1,arg2):
    if arg1 == 0:
        pass
    arg3 = arg1 + arg2
    if arg3 > 1000:
        return arg3
    ret = func(arg2,arg3)
    return ret
print func(0,1)
复制代码
复制代码
 
     
 
     

模块

模块是用一块代码实现某个功能的代码的集合

例如:os是系统相关的模块;file是文件操作相关的模块

模块的种类

  • 自定义模块
  • 内置模块
  • 开源模块

自定义模块

1:定义模块

    自己编写的实现某个功能的.py文件,就称之为定义了一个模块

2:导入模块

模块要想使用,首先要导入模块,模块的导入有以下的几种方式:

  1. import module
  2. from module.x.x import x
  3. from module.x.x import x as rename
  4. from module.x.x import *

导入模块其实就是告诉python解释器去解释哪个py文件 

  • 导入一个py文件,解释器解释该py文件
  • 导入一个包,解释器解释该包下的__init__.py文件

导入模块的路径

  1: import sys
  2: print sys.path
  3: 结果:
  4: ['E:\\python\\day5', 'E:\\python', 'C:\\Windows\\SYSTEM32\\python27.zip', 'C:\\Python27\\DLLs', 'C:\\Python27\\lib', 'C:\\Python27\\lib\\plat-win', 'C:\\Python27\\lib\\lib-tk', 'C:\\Python27', 'C:\\Python27\\lib\\site-packages']

还可以往里追加你想要的路径:sys.path.append(‘路径’)

通过os模块可以获取各种目录,例如:

  1: import sys
  2: import os
  3: pre_path = os.path.abspath('../')
  4: print pre_path
  5: sys.path.append(pre_path)

开源模块

下载安装

方式一:

# yum  
# pip 
# apt-get

方式二:

# 下载源码 
# 解压源码 
# 进入目录 
# 编译解码     python setup.py build 
# 安装源码     python setup.py install

注释:

        因为是源码安装,需要使用gcc和python开发环境

yum –y install gcc 
yum –y install python-devel

安装成功后,模块会自动安装到sys.path中的某个目录

导入模块

和自定义模块中的导入方法是一致的

范例:

模块paramiko

paramiko是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作。fabric和ansible内部的远程管理就是使用paramiko来实现的

1:下载安装

复制代码
复制代码
# pycrypto,由于 paramiko 模块内部依赖pycrypto,所以先下载安装pycrypto

 

# 下载安装 pycrypto

wget http://files.cnblogs.com/files/wupeiqi/pycrypto-2.6.1.tar.gz

tar -xvf pycrypto-2.6.1.tar.gz

cd pycrypto-2.6.1

python setup.py build

python setup.py install


#  进入python环境,导入Crypto检查是否安装成功
#  import Crypto

 
# 下载安装 paramiko

wget http://files.cnblogs.com/files/wupeiqi/paramiko-1.10.1.tar.gz

tar -xvf paramiko-1.10.1.tar.gz

cd paramiko-1.10.1

python setup.py build

python setup.py install

 
#  进入python环境,导入paramiko检查是否安装成功
#   import paramiko
复制代码
复制代码

2:使用模块

执行命令--通过用户名和密码连接服务器

复制代码
复制代码
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('10.0.0.9',22,'root','123456')
stdin,stdout,stderr = ssh.exec_command('df')
print stdout.read()
ssh.close()
结果:
root@python:/server/scripts# python 10.py 
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/sda3       19276064 1532552  16757656   9% /
tmpfs             508148       0    508148   0% /dev/shm
/dev/sda1         194241   36013    147988  20% /boot
复制代码
复制代码

内置模块

1:os

用于提供系统级别的操作

复制代码
复制代码
import os
os.getcwd()                     # 获取当前工作目录
os.chdir()                      # 改变当前脚本工作目录;相当于shell下cd
os.curdir                       # 返回当前目录:('..')
os.pardir                       # 获取当前目录的父目录的字符串名:('..')
os.makedirs('dirname1/dirname2')# 可生成多层递归目录
os.removedirs('dirname1')       # 若目录为空,则删除;并递归到上一级目录;若也为空,则删除,依此类推
os.mkdir('dirname')             # 生成单级目录;
os.listdir('dirname')           # 列出指定目录下所有文件和子目录,包括尹灿文件,并以列表的方式打印
os.remove()                     # 删除一个文件
os.rename('oldname','newname')  # 重命名文件/目录
os.stat('path/filename')        # 获取文件/目录信息
os.sep                          # 输出操作系统特定的路径分隔符,win:\\ linux:/
os.linesep                      # 输出当前平台使用的行终止符,win:\t\n  linux:\n
os.pathsep                      # 输出用于分割文件路径的字符串
os.name                         # 输出字符串指示当前使用平台win: nt  linux: posix
os.system('bash command')       # 运行shell命令,直接显示
os.environ                      # 获取系统环境变量
os.path.abspath()               # 返回path规范化的绝对路径
os.path.split()                 # 将path分割成目录和文件名二元组返回
os.path.dirname()               # 返回path的目录,其实就是os.path.split(path)的第一个元素
os.path.basename()              # 返回path最后的文件名。如果path是以/或\结尾的的,返回是空值
os.path.exists()                # 如果路径存在则返回True
os.path.isabs()                 # 如果path是绝对路径,则返回True
os.path.isfile()                # 如果path是一个存在的文件,返回值为True
os.path.isdir()                 # 如果path是一个存在的目录,返回值为True
os.path.join()                  # 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path)          # 返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path)          # 返回path所指向的文件或者目录的最后修改时间
复制代码
复制代码

2:sys

用于提供对解释器相关的操作

复制代码
复制代码
sys.argv                            # 命令行参数list,第一个元素是程序本身路径
sys.exit(n)                         # 退出程序,正常退出时exit(0)
sys.version                         # 获取python解释程序的版本信息
sys.maxint                          # 最大的int值
sys.path                            # 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform                        # 返回操作系统平台名称
sys.stdout.write('please:')
val = sys.stdin.readline()[:-1]
复制代码
复制代码

3:hashlib

用于加密想关的操作,代替了MD5模块和sha模块

复制代码
复制代码
import hashlib
hash = hashlib.md5('123456')                # 添加一个自定义的Key
hash.update('admin')                        # 实际要加密的Key
print hash.hexdigest()                      # 输出最终加密后的值
# 结果: b9d11b3be25f5a1a7dc8ca04cd310b28
#========================================================================================================
使用hmac模块,他在内部对我们创建的key和内容再进行处理后再加密
import hmac
h = hmac.new('123456')
h.update('admin')
print h.hexdigest()
# 结果: 20238ad293024e2ea2f505db927cd52e
复制代码
***************当你发现自己的才华撑不起野心时,就请安静下来学习吧***************
本文转自散尽浮华博客园博客,原文链接:http://www.cnblogs.com/kevingrace/p/5569929.html ,如需转载请自行联系原作者
相关文章
|
4月前
|
测试技术 数据安全/隐私保护 开发者
探索Python中的装饰器:从基础到高级应用
装饰器在Python中是一个强大且令人兴奋的功能,它允许开发者在不修改原有函数代码的前提下增加额外的功能。本文将通过具体代码示例,带领读者从装饰器的基础概念入手,逐步深入到高级用法,如带参数的装饰器和装饰器嵌套等。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧。
|
4月前
|
开发框架 数据建模 中间件
Python中的装饰器:简化代码,增强功能
在Python的世界里,装饰器是那些静悄悄的幕后英雄。它们不张扬,却能默默地为函数或类增添强大的功能。本文将带你了解装饰器的魅力所在,从基础概念到实际应用,我们一步步揭开装饰器的神秘面纱。准备好了吗?让我们开始这段简洁而富有启发性的旅程吧!
77 6
|
4月前
|
开发者 Python
探索Python中的装饰器:从基础到高级应用
本文将带你深入了解Python中的装饰器,这一强大而灵活的工具。我们将一起探讨装饰器的基本概念,它们如何工作,以及如何使用它们来增强函数和类的功能,同时不改变其核心逻辑。通过具体代码示例,我们将展示装饰器的创建和使用,并探索一些高级应用,比如装饰器堆栈和装饰带参数的装饰器。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的视角,帮助你更有效地使用装饰器来简化和优化你的代码。
|
3月前
|
测试技术 数据库 Python
Python装饰器实战:打造高效性能计时工具
在数据分析中,处理大规模数据时,分析代码性能至关重要。本文介绍如何使用Python装饰器实现性能计时工具,在不改变现有代码的基础上,方便快速地测试函数执行时间。该方法具有侵入性小、复用性强、灵活度高等优点,有助于快速发现性能瓶颈并优化代码。通过设置循环次数参数,可以更准确地评估函数的平均执行时间,提升开发效率。
142 61
Python装饰器实战:打造高效性能计时工具
|
3月前
|
设计模式 前端开发 Shell
Python装饰器是什么?
装饰器是Python中用于动态修改函数、方法或类功能的工具,无需改变原代码。通过将函数作为参数传递并返回新函数,装饰器可以在原函数执行前后添加额外逻辑。例如,使用`@logger`装饰器可以打印函数调用日志,而`@timethis`则可用于计算函数执行时间。为了保持被装饰函数的元信息(如`__name__`和`__doc__`),可使用`functools.wraps`装饰器。此外,带参数的装饰器可通过嵌套函数实现,如`@timeitS(2)`,以根据参数条件输出特定信息。
109 59
|
4月前
|
缓存 Python
深入理解Python中的装饰器
本文旨在通过具体实例和详细解释,帮助读者深入理解Python中装饰器的工作原理及其在实际开发中的应用。我们将从装饰器的基本概念开始,逐步深入到其高级用法,包括自定义装饰器、带参数的装饰器以及类装饰器等。通过本文的学习,读者将能够掌握装饰器的核心思想,提高代码的可读性和可维护性。
|
4月前
|
缓存 数据安全/隐私保护 Python
python装饰器底层原理
Python装饰器是一个强大的工具,可以在不修改原始函数代码的情况下,动态地增加功能。理解装饰器的底层原理,包括函数是对象、闭包和高阶函数,可以帮助我们更好地使用和编写装饰器。无论是用于日志记录、权限验证还是缓存,装饰器都可以显著提高代码的可维护性和复用性。
65 5
|
4月前
|
测试技术 Python
探索Python中的装饰器:简化代码,增强功能
在Python的世界中,装饰器是那些能够为我们的代码增添魔力的小精灵。它们不仅让代码看起来更加优雅,还能在不改变原有函数定义的情况下,增加额外的功能。本文将通过生动的例子和易于理解的语言,带你领略装饰器的奥秘,从基础概念到实际应用,一起开启Python装饰器的奇妙旅程。
68 11
|
4月前
|
测试技术 开发者 Python
探索Python中的装饰器:从入门到实践
装饰器,在Python中是一块强大的语法糖,它允许我们在不修改原函数代码的情况下增加额外的功能。本文将通过简单易懂的语言和实例,带你一步步了解装饰器的基本概念、使用方法以及如何自定义装饰器。我们还将探讨装饰器在实战中的应用,让你能够在实际编程中灵活运用这一技术。
68 7
|
4月前
|
程序员 测试技术 数据安全/隐私保护
深入理解Python装饰器:提升代码重用与可读性
本文旨在为中高级Python开发者提供一份关于装饰器的深度解析。通过探讨装饰器的基本原理、类型以及在实际项目中的应用案例,帮助读者更好地理解并运用这一强大的语言特性。不同于常规摘要,本文将以一个实际的软件开发场景引入,逐步揭示装饰器如何优化代码结构,提高开发效率和代码质量。
97 6