【Python学习笔记】五、函数

1.创建函数

定义函数使用def语句

#计算斐波那契数列
def fibs(n):
    res=[0,1]
    for i in range(n-2):
        res.append(res[-1]+res[-2])
    return res
while True:
    m=int(input())
    print(fibs(m))
#Input:7
#Output:[0, 1, 1, 2, 3, 5, 8]

2.函数的文档注释

为函数添加文档注释,需要在def语句那一行的下一行用一对单引号或双引号将注释括起来。
为函数写了文档注释后,可以使用“__ doc __”函数或“ help ”函数获取函数的文档注释。

def fibs(n):
    "计算斐波那契数列"
    res=[0,1]
    for i in range(n-2):
        res.append(res[-1]+res[-2])
    return res

help(fibs)
#Output:
fibs(n)
    计算斐波那契数列
    
print(fibs.__doc__)
#Output:计算斐波那契数列

3.函数参数的传递

如果传递的变量类型是数值、字符串、布尔等类型,则是值传递

值传递即在传递时将自身复制一份,函数内部接收到的参数实际上是传递给函数的变量的副本,故在函数内部对参数变量进行修改并不会影响到原始变量。

如果传递的变量类型是序列、对象等复合类型,则是引用传递

引用传递即在传递时复制的不是变量中的数据,而是变量的引用。因为这些复合类型在内存是用一块连续或不连续的内存空间保存,要想找到这些复合类型的数据,必须得到这些内存空间的首地址,而这个首地址就是复合类型数据的引用。故在函数内部对复合类型参数变量进行修改也会影响到原始变量。

4.关键字参数

def qqq(name,age):
    return "名字:{},年龄:{}".format(name,age)

#使用位置参数,传递过去的值是位置对应的
print(qqq("Bill",12)) #Output: 名字:Bill,年龄:12

#使用关键字参数,位置可以随意
print(qqq(age=10,name="Mike")) #Output: 名字:Mike,年龄:10

#上述两种混用,关键字参数必须放在位置参数后面,否则会抛出异常
print(qqq("John",age="20")) #Output: 名字:John,年龄:20

5.可变参数

像print函数这样可以传递任意多个参数的形式称为可变参数。定义函数的可变参数需要在形参前面加一个星号(*)

可变参数在函数内部是以元组的形式体现的,故在函数内部可以像元组一样使用可变参数的具体参数值。

def output(*p):
    print(p)
output("hello",2,True,100) #Output:('hello', 2, True, 100)

既有普通参数又有可变参数时,可变参数要放在最后。若想放在中间或最前面,则其后面的普通参数在进行参数值传递时要使用关键字参数形式,或者为后面的普通参数指定默认值。

def output(val,*p): 
    print(val,end=" ")
    for i in p:
        print("<"+str(i)+">",end=" ")
output("hello",2,True,100) #Output:<hello> <2> <True> <100>

6.将序列作为函数的参数值

除了可以直接将序列作为单个的参数传入函数外,我们还可以将序列的每个元素单独作为函数的参数值,相当于把序列拆开进行传值。

将序列(列表、元组、字典、字符串等)中的元素拆开成单个参数传递给函数,需要在实参前面加星号(*)。

def Output1(s1,s2,s3): #传递进来的序列元素有几个则形参就得有几个
    print(s1,s2,s3)

def Output2(*s): #或者用可变参数
    print(s,end=" ")
    for i in s:
        print(i,end="~")

L=["hello","world",2020]
Output1(*L) #Output:hello world 2020
Output2(*L) #Output:('hello', 'world', 2020) hello~world~2020~
Output2(L) #Output:(['hello', 'world', 2020],) ['hello', 'world', 2020]~

#Output1(*"LOVE") #出现异常,函数形参只有3个
Output2(*"LOVE") #Output:('L', 'O', 'V', 'E') L~O~V~E~
Output2("LOVE") #Output:('LOVE',) LOVE~

将字典中的元素作为单个参数传入函数时,形参实参都要使用两个星号。

def Output1(**s):
    print(s,end=" ")
    for i in s:
        print(i,end="~")
def Output2(s):
    print(s,end=" ")
    for i in s:
        print(i,end="~")

L={'a':1,'b':2,'c':3}
Output1(**L) #Output:{'a': 1, 'b': 2, 'c': 3} a~b~c~
Output2(L) #Output:{'a': 1, 'b': 2, 'c': 3} a~b~c~

7.作用域

作用域分为全局作用域和在函数本身的局部作用域。
在python语言中,不管在作用域的哪个位置为变量赋值,都会认为这个变量属于当前作用域,而且会隐藏上层作用域同名的变量。
如果在当前函数中没有定义局部变量x,那么当前函数会从上一个作用域开始查找,直到找到变量x或到了全局作用域为止。

x=123
def fun():
    print(x) #先访问全局变量x,再定义局部变量x,这是不行的,会抛出异常
    x=10
fun()

8.函数嵌套和返回函数以及闭包

python语言中,函数支持嵌套,即可以在一个函数中定义另一个函数。并且可以直接返回函数本身(相当于C中返回函数的指针)

x=30
def fun1():
    x=10
    def fun2(): #嵌套函数
        print(x)
    return fun2 #返回fun2函数本身

fun1()() #调用了fun1的嵌套函数fun2
#Output:10

关于返回函数:

def fun(y):
    def cal(x):
        return 2*x+y
    return cal

qwe=fun(4) 
print(qwe(5)) #Output:14
print(fun(4)(3)) #Output:10

闭包:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure).
(上面两份代码均是闭包的示例,具体内容及作用待以后学习)

9.global关键字和nonlocal关键字

函数内部不支持对不在当前作用域的变量进行修改,示例如下。

#函数内部修改全局作用域变量
def qqq1():
    x+=1 #x是全局变量,能直接访问和直接使用,但不能进行修改
    print(x)
def qqq2():
    x=20 #在函数局部作用域重新定义了x,会覆盖全局x,所以能进行修改了
    x+=1
    print(x)
x=100
qqq1() #UnboundLocalError: local variable 'x' referenced before assignment
qqq2() #Output:21
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#函数内部修改上一个作用域变量
def www():
    y=10
    def eee():
        y+=1 #y是上一个作用域的变量,所以也不能修改,只能直接访问和使用
        print(y)
    return eee
www()() #UnboundLocalError: local variable 'y' referenced before assignment

若想对不在当前作用域的变量进行修改,则需要使用global关键字或nonlocal关键字,示例如下。

#在函数中需要修改全局变量,则需要使用global关键字
def qqq1():
    global x
    x+=1 
    print(x)
x=100
qqq1() #Output:101
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#在函数中需要修改上一级作用域变量,则需要使用nonlocal关键字
def www():
    y=10
    def eee():
        nonlocal y
        y+=1
        print(y)
    return eee
www()() #Output:11
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值