Python自动化运维之函数进阶

1、函数嵌套
函数的嵌套定义:在一个函数的内部,又定义了另外一个函数
函数的嵌套调用:在调用一个函数的过程中,又调用了其他函数
代码:

>>> def f1():
...     def f2():
...         print(‘from f2‘)
...         def f3():
...             print(‘from f3‘)
...         f3()
...     f2()
...

执行结果:

>>> f1()
from f2
from f3

2、命名空间与作用域:存放名字的地方,确切的是存放的名字与变量值的绑定的关系的空间
名称空间分类:内置名称空间、全局名称空间和局部名称空间
    内置名称空间:Python解释器启动时产生一些内置名字
    全局名称空间:在执行文件时产生的,存放在文件级别(流程控制语句定义、未缩进定义的)定义的名字
    局部名称函数:
    加载顺序:内置---->全局---->局部
    名称查找顺序:局部---->全局---->内置
作用域:作用的范围
    作用域分类:全局作用域和局部作用域
    全局作用域:全局存活,全局有效。查看函数globals(),显示字典类型
    局部作用域:临时存活,局部生效。查看函数locals(),显示字典类型
关键字:global nonlocal
局部修改全局,对于不可变类型需要使用global,可变类型无需使用global
局部修改局部,对于不可变类型需要使用nonlocal,可变类型无需使用nonlocal
注意:尽量避免使用局部修改全局
重点:作用域关系,在函数定义时,函数中名称查找就已经固定和调用位置无关。在调用函数时,必须回到函数原来定义的位置去找作用域关系

x = 1
def f1():
    def f2():
        print(x) # x 为全局作用域
    return f2()
def foo():
    x = 100
    f1()
foo()
x = 10
foo()

3、闭包函数
闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。
闭包可以形象的把它理解为一个封闭的包裹,这个包裹就是一个函数,当然还有函数内部对应的逻辑,包裹里面的东西就是自由变量,自由变量可以在随着包裹到处游荡。当然还得有个前提,这个包裹是被创建出来的。
在Python中可以这样理解,一个闭包就是我调用了一个函数A,这个函数A返回了一个函数B给我。这个返回的函数B就叫做闭包。我在调用函数A的时候传递的参数就是自由变量。

1. 定义
python中的闭包从表现形式上定义(解释)为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure).这个定义是相对直白的,好理解的,不像其他定义那样学究味道十足(那些学究味道重的解释,在对一个名词的解释过程中又充满了一堆让人抓狂的其他陌生名词,不适合初学者)。下面举一个简单的例子来说明。

>>> def addx(x):
...     def adder(y): return x + y
...     return adder
...
>>> c = addx(8)
>>> type(c)
<class ‘function‘> 
>>> c.__name__
‘adder‘ 
>>> c(10)
18

结合这段简单的代码和定义来说明闭包:如果在一个内部函数里:adder(y)就是这个内部函数,对在外部作用域(但不是在全局作用域)的变量进行引用:x就是被引用的变量,x在外部作用域addx里面,但不在全局作用域里,则这个内部函数adder就是一个闭包。
闭包=函数块+定义函数时的环境,adder就是函数块,x就是环境,当然这个环境可以有很多,不止一个简单的x。所以,如果要用一句话说明白闭包函数,那就是:函数内在包含子函数,并最终return子函数。
2. 使用闭包注意事项
2.1 闭包中是不能修改外部作用域的局部变量的

>>> def foo():
...     m = 0
...     def foo1():
...         m = 1
...         print(m)
...     print(m)
...     foo1()
...     print(m)
...
>>> foo()
0
1
0

从执行结果可以看出,虽然在闭包里面也定义了一个变量m,但是其不会改变外部函数中的局部变量m。

2.2 以下这段代码是在python中使用闭包时一段经典的错误代码

>>> def foo():
...     a = 1
...     def bar():
...         a = a + 1
...         return a
...     return bar
...

这段程序的本意是要通过在每次调用闭包函数时都对变量a进行递增的操作。但在实际使用时

>>> c=foo()
>>> print(c())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in bar
UnboundLocalError: local variable ‘a‘ referenced before assignment

这是因为在执行代码c=foo()时,python会导入全部的闭包函数体bar()来分析其的局部变量,python规则指定所有在赋值语句左面的变量都是局部变量,则在闭包bar()中,变量a在赋值符号"="的左面,被python认为是bar()中的局部变量。再接下来执行print c()时,程序运行至a = a + 1时,因为先前已经把a归为bar()中的局部变量,所以python会在bar()中去找在赋值语句右面的a的值,结果找不到,就会报错。解决的方法很简单

def foo():  
    a = [1]  
    def bar():  
        a[0] = a[0] + 1  
        return a[0]  
    return bar

只要将a设定为一个容器就可以了。这样使用起来多少有点不爽,所以在python3以后,在a = a + 1 之前,使用语句nonloacal a就可以了,该语句显式的指定a不是闭包的局部变量。

4、装饰器:开发封闭原则:对扩展是开放的,对修改是封闭的。

5、迭代器
    迭代:是一个重复的过程,每一次重复,都是基于上一次的结果而来
    什么是迭代器对象
        有__iter__和__next__方法,并且执行__iter__得到仍是迭代器本身
    迭代器对象的优点
        1. 提供了一种统一(不依赖索引)的迭代方式
        2. 迭代器本身,比起其他数据类型更少内存,next()在内存中只有1个值
    迭代器对象的缺点
        1. 取值不灵活。只能往后走,不能回退,没有索引取值灵活
        2. 无法预知取值结束,即无法预知长度
    判断可迭代器对象与迭代器对象
        from collections import Iterator
        判断是否是可迭代器对象
        print(isinstance(对象,Iterator))
        判断是否是迭代器对象

6、生成器:在函数内存包含yield关键字,那么该函数执行的结果是生成器,并且生成器就是迭代器
    关键字yield的功能
        1. 包函数的结果做出迭代器,以一种优雅的方式封装好__iter__,__next__方法
        2. 函数暂停与再继续运行的状态是有yield保存的

return 和 yield的区别:
    功能相同:都能返回值
    不同:return只能执行一次

7、三元表达式、列表解析、生成器表达式

时间: 2024-11-14 01:34:50

Python自动化运维之函数进阶的相关文章

Python自动化运维之函数

1.函数简介简而言之,函数就是将一些语句集中方在一起的部件,它能够不止一次的在程序中运行.函数还能够计算出一个返回值,并能够改变作为函数输入的参数,而这些参数在代码运行时也许每次都不相同.以函数的形式去编写一个操作可以使它成为一个能够广泛应用的工具,让我们在不同的情形下都能够使用它.更具体地说,函数是在编程过程中剪剪贴贴的替代--我们不再有一个操作的代码的多个冗余副本,而是将代码包含到一个单独的函数中.通过这样做,我们可以大大减少今后的工作:如果这个操作之后必须要修改,我们只需要修改其中的一份拷

Python自动化运维课程学习--Day3

本文为参加老男孩Python自动化运维课程第三天学习内容的总结. 大致内容如下: 1.文件操作 2.字符编码转码相关操作 3.函数 0.关于本文中所有运行Python代码的环境: --操作系统:Ubuntu 16.10 (Linux 4.8.0) --Python版本:3.5.2 python2.7.12 --Python IDE: PyCharm 2016.3.2 一.文件操作: 1.文件操作流程:以只读.写(覆盖写).追加写.读写.追加读写.二进制读写等模式打开文件 ==> 得到文件句柄,并

Python自动化运维课程学习--Day2

本文为参加老男孩Python自动化运维课程第二天学习内容的总结. 大致内容如下: 1.python模块初识 2.python程序运行流程 3.python数据类型(只讲了numbers, bool, strings, bytes, list, tuple, dict, set) 4.python数据运算 0.关于本文中所有运行Python代码的环境: --操作系统:Ubuntu 16.10 (Linux 4.8.0) --Python版本:3.5.2 --Python IDE: PyCharm

(转)Python自动化运维之13、异常处理及反射(__import__,getattr,hasattr,setattr)

Python自动化运维之13.异常处理及反射(__import__,getattr,hasattr,setattr) 一.异常处理 python异常: python的运行时错误称作异常 (1)语法错误:软件的结构上有错误而导致不能被解释器解释或不能被编译器编译 (2)逻辑错误:由于不完整或不合法的输入所致,也可能是逻辑无法生成.计算或者输出结果需要的过程无法执行等 python异常是一个对象,表示错误或意外情况 (1)在python检测到一个错误时,将触发一个异常 python可以通常异常传导机

Python自动化运维Django入门

随着IT运维技术日益更新,近几年运维自动化越来越火,而且学习python的人非常的火爆,尤其是python自动化运维开发,得到了很多前辈的推崇,尤其是老男孩培训中心.老男孩老师.Alex老师等,在这里非常感谢你们. 这里我也记录一下以前学习Django的一点点心得和方法,方便以后自己查阅,如果能帮助初学者是最好的了!好的,其他不多说了,博文滴走起. 一.系统实战环境 系统版本:CnetOS6.5 x86_64 Django版本:Django-1.5.8 MySQL版本:MySQL-5.1.73

云计算开发教程:Python自动化运维开发实战流程控制

今天这篇文章是给大家分享一些云计算开发教程,今天讲解的是:Python自动化运维开发实战流程控制. Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块. Python程序语言指定任何非0和非空(null)值为true,0 或者 null为false. if 语句用于控制程序的执行,基本形式为: if 判断条件: 执行语句-- else: 执行语句-- 其中"判断条件"成立时(非零),则执行后面的语句,而执行内容可以多行,以缩进来区分表示同一范

python自动化运维之路~DAY7

python自动化运维之路~DAY7 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.客户端/服务器架构 C/S 架构是一种典型的两层架构,其全称是Client/Server,即客户端服务器端架构,其客户端包含一个或多个在用户的电脑上运行的程序,而服务器端有两种,一种是数据库服务器端,客户端通过数据库连接访问服务器端的数据:另一种是Socket服务器端,服务器端的程序通过Socket与客户端的程序通信. C/S 架构也可以看做是胖客户端架构.因为客户端需要实现绝大多数的业务

python自动化运维之路~DAY10

python自动化运维之路~DAY10 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.

python自动化运维之集中病毒扫描

1.因为我linux的python是2.6.6,所以因为有些模块是2.7的,先进行升级. 步骤地址:http://www.linuxidc.com/Linux/2014-07/104555.htm 2.安装pyclamd yum install -y clamav clamd clamav-update 安装clamavp的相关程序包 chkconfig --level 235 clamd on /usr/bin/freshclam pyClamd-0.3.15.tar.gz安装包安装 3.vi