Python函数高级应用

变量作用域

1)全局变量

  • 标识符的作用域是定义为其声明在程序里的可应用范围,也就是变量的可见性
  • 在一个模块中最高级别的变量有全局作用域
  • 全局变量的一个特征是除非被删除掉,否则它们的存活到脚本运行结束,且对于所有的函数,他们的值都是可以被访问的
>>> a = 10
>>> def func1():
...   print(a)
...
>>> func1()
10
# 在函数内定义的变量是局部变量,只能在函数内使用
>>> def func2():
...   b = 100
...   print(b)
...
>>> func2()
100
>>> print(b)   # Error,全局没有b这个名字
# 如果函数内和全局有相同的名字,函数内的名字将会遮盖住全局的名字
>>> def func3():
...   a = 'hello world'
...   print(a)
...
>>> func3()
hello world
>>> print(a)   # 全局变量a的值仍然是10
10
# 如果需要在函数内(局部)改变全局的值,可以使用global关键字
>>> def func4():
...   global a
...   a = 1000
...   print(a)
...
>>> print(a)
10
>>> func4()
1000
>>> print(a)
1000

2)局部变量

  • 局部变量只时暂时地存在,仅仅只依赖于定义它们的函数现阶段是否处于活动
  • 当一个函数调用出现时,其局部变量就进入声明它们的作用域。在那一刻,一个新的局部变量名为那个对象创建了
  • 一旦函数完成,框架被释放,变量将会离开作用域
  • 如果函数内有局部变量的name与全局变量相同,那么在引用时,优先局部变量

函数式编程

1)偏函数

  • 偏函数的概念是将函数式编程的概念和默认参数以及可变参数结合在一起
  • 一个带有多个参数的函数,如果其中某些参数基本上固定的,那么就可以通过偏函数为这些参数赋默认值
>>> def add(a,b,c,d,e):
...     print(a+b+c+d+e)
... 
>>> add(1,2,3,4,5)
15
>>> add(1,2,3,4,6)
16
>>> add(1,2,3,4,7)
17
>>> import functools
>>> add2 = functools.partial(add,1,2,3,4) #改造的函数,位置参数1,位置参数2,位置参数3,位置参数4
>>> add2(5)   #此时abcd均有值,所以5为e的值
15
>>> add2(6)
16
>>> add2(7)
17
>>> 
>>> int('10101100',base=2)  #base=2表示被转换的数字为2进制数
172
>>> int2 = functools.partial(int,base=2) #使用偏函数改造,将base=2设为默认
>>> int2('10101100')
172
#简单的gui图形程序
import tkinter
from functools import partial
root = tkinter.Tk()    #创建顶层窗口
lb1 = tkinter.Label(root, text="hello world!", font = "Aria 16 bold")#创建标签
b1 = tkinter.Button(root, bg='blue', fg='white', text="Button 1")#创建按钮
mybutton = partial(tkinter.Button, root, bg='blue', fg='white')
#调用新的函数时,给出改变的参数即可
b2 = mybutton(text='Button 2')
b3 = tkinter.Button(root, bg='red', fg='red', text='QUIT', command=root.quit)    #创建按钮,绑定了root.quit命令
lb1.pack()    #填充到界面
b1.pack()
b2.pack()
b3.pack()
root.mainloop()    #运行这个GUI应用

2)递归函数

  • 如果函数包含了对其自身的调用,该函数就是递归的
  • 在操作系统中,查看某一目录内所有文件、修改权限等都是递归的应用
# 阶乘函数,例:5!=5*4*3*2*1   5!=5*4!   ...
def func(x):
    if x == 1:
        return 1
    return x * func(x - 1)

if __name__ == '__main__':
    print(func(5))
# 指定序列对象进行快速排序
from random import randint

def qsort(seq):
    '接受一个序列对象,返回排序结果'
    if len(seq) < 2:
        return seq

    # 假设第1项是中间值
    middle = seq[0]
    smaller = []
    larger = []
    # 遍历后续项,比middle小的放到samller,比middle大的放到larger
    for data in seq[1:]:
        if data < middle:
            smaller.append(data)
        else:
            larger.append(data)

    # 把3项数据拼接
    return qsort(smaller) + [middle] + qsort(larger)

if __name__ == '__main__':
    nums = [randint(1, 100) for i in range(10)]
    print(nums)
    result = qsort(nums)
    print(result)

生成器

  • 生成器表达式:和列表解析有一样的语法格式
>>> ['192.168.1.%s' % i for i in range(1, 255)] #列表解析
>>> ips = ('192.168.1.%s' % i for i in range(1, 255)) #生成器
>>> print(ips)
<generator object <genexpr> at 0x7f007b5b82b0>
>>> for ip in ips:
...   print(ip)
  • 生成器函数:本质上还是函数
    • 生成器函数可以通过yield关键字返回很多中间值
>>> def mygen():
...   yield 100
...   a = 10 + 20
...   yield a
...   yield 'Hello World'
...
>>> mg = mygen()   # 创建一个生成器对象
>>> next(mg)       # 从生成器对象中取值
100
>>> next(mg)
30
>>> next(mg)
'Hello World'
>>> next(mg)       # 生成器对象无值可取的时候,返回StopIteration异常
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

>>> mg = mygen()
>>> for data in mg:
...   print(data)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章