Python之函数的常用知识点(举例说明函数特殊用法、变量的作用域和查找规则、全局变量和局部变量、global和nonlocal的使用、可迭代对象、迭代器、装饰器的概念及使用、递归的概念及使用)

举例说明函数的特殊用法:

  • 变量可以指向函数
def test():
    pass

f = test
f()
  • 函数名是一个变量
test = 10
test()
  • 函数可以作为参数使用
def fun(f):
    f()

fun(test)

 变量的作用域:

  • 概念:变量的作用域指的是一个变量可以被使用【访问】的范围。程序中的变量并不是在任何地方都可以访问的,访问的权限取决于这个变量被定义在什么位置【直接定义,语句中,函数中】
  • 作用范围的划分:局部作用域【L:local】、函数作用域(体现在闭包中)【E:enclosing】、全局作用域【G:global】、内键作用域(内置作用域)【B:Built-in】
  • 变量的查找规则:L——>E——>G——>B(注意:全局作用域和内键作用域并没有严格顺序,主要由先后顺序决定查找规则)

变量的查找规则:

  • 四种变量由不同的命名
num3 = 30              #全局作用域

num4 = int(2.9)        #内置作用域【系统内置功能返回的值赋值给一个变量】

def outer():
    num1 = 10          #函数的作用域
    def inner():
        num2 = 20      #局部作用域【局部作用域并不是绝对的】
        print(num1,num2,num3,num4)    #10 20 30 2
        #结论:在闭包的内部函数中,可以访问全局,内置,函数
    return inner

f = outer()
f()
  • 四种变量有相同的命名【就近原则】
x = int(3.2)
x = 10
def outFunc():
    x = 20
    def innerFunc():
        x = 30
        print(x)             #30
        #结论:如果所有的变量同名,就近原则,看哪个语句距离此语句最近
    return innerFunc

f1 = outFunc()
f1()

注意:python中只有模块【module】,类【class】和函数【def,lambda】会引入新的作用域,在模块外面是访问不到的。其他代码块,如:while语句,for语句,try-except语句是不会引入新的作用域的,即在这些语句中定义的变量,在语句外面也可以进行访问

全局变量和局部变量【尽量避免两种变量重名情况,如发生则就近原则】: 

  • 全局变量:定义在函数外面,在当前整个py文件中都可以任意访问
  • 局部变量:定义在函数中,只能在当前函数中访问

global和nonlocal关键字的使用: 

  • 如果在函数内部出现了和全局变量重名的局部变量,而在局部变量定义之前要访问全局变量,则需要使用global关键字对全局变量进行声明
num = 1
def fun1():
    #需求:访问全局num
    #解决办法:在访问全局变量之前作出声明
    global num
    print(num)                #1
    num = 123
    print(num)                #123

fun1()
  • nonlocal的使用只能出现在闭包中【将小作用域范围变大一层】
x = 0        #全局作用域

def outer():
    x = 1                  #函数作用域

    def inner():
        nonlocal x        #将此部分x的作用域变大,即将变量的局部作用域修改为函数作用域
        x = 2              #局部作用域
        print("inner:",x)  #2
    inner()
    print("outer:",x)      #2

outer()
print("global",x)          #0

 迭代器:

  • 可迭代对象     
  1. 概念:可以直接作用于for循环的对象【实体】被称为可迭代对象:Iterable                                       
  2. 分类:可以直接作用于for循环的数据类型:集合数据类型,包含list,tuple,dict,set,string  generator,包含()生成器和yield的生成器                                                                                       
  3. 判断:isinstance()【instance:对象,实体,实例】可以用来判断一个对象(实体)是否可迭代对象   isinstance(数据,Interable)
#第一步:导入模块
from collections import Iterable
#import collections

#第二步:判断
print(isinstance([],Iterable))                      #True
print(isinstance((),Iterable))                      #True
print(isinstance({},Iterable))                      #True
print(isinstance(set([]),Iterable))                 #True
print(isinstance("hello",Iterable))                 #True
print(isinstance((i for i in range(10)),Iterable))  #True
print(isinstance(10,Iterable))                #False
print(isinstance(True,Iterable))              #False
  • 迭代器                                                                                                                                                       
  1. 概念:不但可以直接用于for循环,还可以使用next()函数进行获取元素值,同时符合这两种条件的数 据被称为迭代器【Interator】,只有生成器是迭代器                                                                           
  2. 判断:isinstance()可以用来判断一个对象【实体】是否是迭代器
#第一步:导入模块
from collections import Iterator
#import collections

print(isinstance([],Iterator))                      #False
print(isinstance((),Iterator))                      #False
print(isinstance({},Iterator))                      #False
print(isinstance(set([]),Iterator))                 #False
print(isinstance("hello",Iterator))                 #False
print(isinstance((i for i in range(10)),Iterator))  #True
print(isinstance(10,Iterator))                #False
print(isinstance(True,Iterator))              #False

#可以使用系统内置的功能iter(),可以将可迭代对象转换为迭代器【除了生成器之外的可迭代对象】
list1 = [41,51,5]
a = iter(list1)
print(next(a))

list2 = [41,546,12]
b = iter(list2)
while True:
    try:
        x = next(b)
    except StopIteration:
        print("元素已经获取完成")
        break

注意:可迭代对象不一定是迭代器,迭代器肯定是可迭代对象                                                               

装饰器:简单装饰器、带参数装饰器、使用@标识符将装饰器直接应用到函数、带有不定长参数的装饰器、将多个装饰器应用在同一个函数上

  • 本质:dectorator 增强一个函数的功能,又不修改原有函数,在代码运行期间动态给函数增加功能方式装饰器实际上是一个闭包【将需要装饰的函数作为参数传递给闭包,然后将装饰之后的结果返回】
  • 优势:在不用修改源代码的前提下增加函数功能【动态性】
#简单装饰器
#第一步:书写闭包
#第二步:给外部函数设置参数
def outer(fun):
    def inner():
        #第三步:在内层函数中调用需要被装饰的函数
        fun()
        #第四步:增加新功能
        print("Let's go outside")
    return inner

#第五步:使用闭包
f = outer(now)    #函数可以作为参数使用
f()

注意:增加的功能可以写在原函数调用的前面或者后面,没有严格的区分。上述代码中outer被称为装饰器,inner被称为装饰器的工作核心

#有参数的装饰器
def getAge(age):
    print(age)

#问题:输出若为负数,则不符合常理   
getAge(10)
getAge(-5)

#需求:用装饰器实现:当用户输入的age为负数的时候,将其置为0
def outer2(f):
    def inner2(age):
        f(age)
        if age > 0:
            print(age)
        else:
            print("输出有误")
    return inner2

f2 = outer2(getAge)
f2(-5)

注意:当原函数有参数,装饰器的额作用是为了操作原函数中的参数,则要在闭包inner内传入参数,调用的时候也给入参数


#使用@标识符将装饰器直接应用到函数
def wrapper(f):
    def inner(num):
        if num < 0:
            num = 0
        f(num)
    return inner

@wrapper
def getAge1(age):
    print(age)

getAge1(-5)

注意:使用@之后,装饰器必须先被定义,然后再使用到原函数,此时原函数也相当于被增加新功能

#4.带有不定长参数的装饰器
def wrapper(fun):
    def inner(*args,**kargs):
        fun(*args,**kargs)
        print("hello")           #新功能
    return inner

@wrapper
def fun1(a,b):
    print(a + b)               #30 hello

fun1(10,20)

@wrapper
def fun2(a,b,c):
    print(a * b * c)           #6 hello

fun2(1,2,3)

注意:将一个装饰器应用到不同函数上

#5.将多个装饰器应用在同一个函数上
def wrapper1(fun):
    def inner(*args,**kargs):
        fun(*args,**kargs)
        print("hello world1")           
    return inner

def wrapper2(fun):
    def inner(*args,**kargs):
        fun(*args,**kargs)
        print("hello world2")           
    return inner

@wrapper1
@wrapper2
def test():
    print("test")
    
test()           #test  hello world2  hello world1

注意:多个装饰器应用于同一个函数的时候,原函数只被执行一次,并且是就近原则执行【谁最后出现,谁最先被执行】

 递归的概念及使用:斐波那契数列与求和问题

概念:一个函数调用本身,被称为函数递归【递归调用】。递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复无须用条件控制【但凡使用循环可以解决的问题,一般使用递归解决】

使用递归解决问题需要考虑的因素:

  1. 找到一个临界值【临街条件】
  2. 寻找相邻两次循环之间的关系【公式】
#斐波那契数列
'''
1 2 3 4 5 6  7  8  9 10        报数
1,1,2,3,5,8,13,21,34,55,89,,,,,斐波那契数列
'''
#规律:a.临界值:第一个位置和第二个位置上的数是固定的,都是1
#      b.公式:第n个位置上的数 = 第n-1个位置上的数 + 第n-2位置上的值
def func(num):
    if num == 1 or num == 2:
        return 1
    else:
        return func(num-1) + func(num-2)
    
print(func(10))             #55
#计算1到某个数之间的所有整数的和
def func1(num):
    if num ==1:
        return 1
    else:
        return func1(num-1) + num
    
print(func1(10))

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值