【python】Function(9)

在这里插入图片描述


参考

Note:



(DRY) don’t repeat yourself

函数就是那些做成重复使用的程序代码


1 函数的定义

函数是由函数名、参数和函数体组成,格式如下:

def 函数名(形式参数):

   函数体

   [ return 返回值 ]

eg1:

def subtraction(a,b):
    c = a - b
    return c

python的函数可以返回多个值,默认是元组的形式,也可以以列表的形式返回

return a,b,c #元组
return [a,b,c] #列表

2 函数的调用

subtraction(3,4)

结果为 -1

3 参数的传递

3.1 参数按照位置顺序传递

subtraction(3,4)

结果为-1

3.2 参数按赋值传递

subtraction(b = 3,a = 4)  #参数按赋值传递

结果为1


3.3 参数按照默认值传递

eg2:

def subtraction(a,b=2): #参数按照默认值传递,b使用了默认值
    c = a - b
    return c
subtraction(4)

结果为2

subtraction(4,1)

结果为3


3.4 元组类型的变长度参数传递(可变参数)

参数的拆包

eg3:

def dayin(a,b):
    print(a,b)
dayin(1,2)

结果为
1 2


那么如果要打印1000个数呢?设置1000个形参?那岂不是太麻烦了
定义一个变长参数即可,具体操作如下:
我们可以在参数前面加一个星号 * ,表示这个参数是可变长参数当其他参数赋值完毕时候,剩下的参数依次赋值给这个可变长参数

eg4:

def dayin(a,*b):
    print(a,b)
dayin(1,2,3)

结果为
1 (2, 3)


好像不完美,变长部分以元组的形式呈现,我们要的是1 2 3 的效果,改改

eg5:

def dayin(a,*b):
    print (a,'',end = '') # ''空格,end = ''表示不换行, 
    for i in b:
        print (i,'',end = '')
dayin(1,2,3)

结果为
1 2 3


试试效果

dayin(1,2,3,4,5,6,7,8)

结果为
1 2 3 4 5 6 7 8


*形参叫做收集参数,eg: print 函数
这里写图片描述

3.5 字典类型的变长度参数传递(关键字参数)

我们可以在参数前面加两个星号 ** ,表示这个参数是可变长参数是以 实参名=字典值的方式传递
eg6:

def dayin(a,*b,**c):
    print(a,b,c)
dayin(1,2,3,d = 4)

结果为

1 (2, 3) {'d': 4}

注意到,字典类型变长参数传递一定是赋值形式传递进去的

dayin(1,2,3,4)

结果为

1 (2, 3, 4) {}

dayin(1)

结果为
1 () {}


我们和3.4节一样,改改函数,取出元组和字典中的数字
eg7:

def dayin(a,*b,**c):
    print(a,'',end = '')
    if len(b) != 0:
        for i in b:
            print(i ,'',end = '')
    if len(c)!= 0:
        for j in c:
            print(c[j],'',end = '')
dayin(1,2,3,4,5,6,7,8)

结果为
1 2 3 4 5 6 7 8

dayin(1)

结果为
1

dayin(1,2,3,4,5,haha = 6)

结果为
1 2 3 4 5 6

dayin(1,2,3,4,5,haha = 6,hehe = 7)

结果为
1 2 3 4 5 6 7

dayin(1,2,3,4,5,haha = 6,7,8,9,hehe = 10)
#注意,可变参数的位置一般写在最后,不能乱了顺序,否则会报错!!!

结果报错

SyntaxError: positional argument follows keyword argument

3.6 *args 和 **kwargs

Python中的*args和**kwargs是什么?该如何使用?

args 是 arguments 的缩写,表示位置参数;
kwargs 是 keyword arguments 的缩写,表示关键字参数。

# *arg 的魔法
def func(*arg):
    num = 0
    for x in arg:
        num = num + x
    print(num)  # 600
func(100, 200, 300)


def printPetNames(*args, **kwargs):
    for i in args:
        print(f"Owner Name:{i}")
    for pet, name in kwargs.items():
        print(f"{pet}:{name}")

printPetNames(
    "Jonathan", "Bob", "Alex",
    dog="Brock",
    fish=["Larry", "Curly", "Moe"],
    turtle="Shelldon")

4 无返回值的函数

eg8:

def add():
    a = 1
    b = 2
    print(a+b)
add()

结果为
3

有些编程语言中,如果没有返回值(return),叫做过程
python严格来说是没有过程的,因为即使函数中没有return语句,python会默认返回None


5 函数的作用域

变量的作用域就是在程序中能对这个变量操作的区域范围,Python允许同名变量的出现
eg9:

a = 0
def outer():
    a = 1
    print('outer = %d'%a)
    def inner():
        a = 2
        print('inner = %d'%a)
outer()

结果为
outer = 1

Note:以上,我们调用outer( ),inner( ) 函数只是定义了,并没有调用,所以不会运行这个inner( )的函数体


eg10:

a = 0
def outer():
    a = 1
    print('outer = %d'%a)
    def inner():
        a = 2
        print('inner = %d'%a)
    inner() # 在outer()中新增了对inner()的调用
outer()

结果为
outer = 1
inner = 2

此时

print(a)

结果为
0

Noete:以上,注意到,a变量分别有三次赋值,这里的赋值不是覆盖了,因为他们三个a是在不同的位置

  • 值为 0 的 a 是在函数外面,我们称之为全局变量(即它的作用域是全局的)

  • 值为 1 的 a 的作用范围是outer( )函数中

  • 值为 2 的 a 的作用范围是inner( )函数中

当我们要使用变量时候,先在最近的区域搜索


下面在eg10的基础上,注释一些a的赋值,看看结果,以便更好的掌握函数的作用域

5.1 注释a等于1

eg11:

a = 0
def outer():
    #a = 1
    print('outer = %d'%a)
    def inner():
        a = 2
        print('inner = %d'%a)
    inner()
print ('whole = %d'%a)
outer()

结果为

whole = 0
outer = 0
inner = 2

当我们把 a = 1 注释掉,则外层函数打印 a 的时候,取的全局变量,因为内层函数的作用域只在内层函数中,不能延伸到外层函数。


5.2 注释a等于2

eg12:(★★★★★)

a = 0
def outer():
    a = 1
    print('outer = %d'%a)
    def inner():
        #a = 2
        print('inner = %d'%a)
    inner()
print ('whole = %d'%a)
outer()

结果为

whole = 0
outer = 1
inner = 1

以上,把内层函数里的 a 注释掉,则内层函数使用的 a 是外层函数定义的 a,因为,外层函数距离内层函数比全局变量距离内层函数更近。


Note:不要将变量的作用域和变量重复赋值覆盖搞混,看以下的例子
eg13:

a = 0
a = 4
def outer():
    a = 1
    print('outer = %d'%a)
    def inner():
        #a = 2
        print('inner = %d'%a)
    inner()
print ('whole = %d'%a)
outer()

结果为

whole = 4
outer = 1
inner = 1

5.3 注释a等于1和2

如果外层函数没有定义 a ,则会去取全局变量
eg14:

#如果外层函数没有定义 a ,则会去取全局变量
a = 0
def outer():
    #a = 1
    print('outer = %d'%a)
    def inner():
        #a = 2
        print('inner = %d'%a)
    inner()
print('whole = %d'%a)
outer()

结果为

whole = 0
outer = 0
inner = 0

6 匿名函数 lambda

匿名函数,匿名指的是我们不知道这个函数的名字,当我们使用时候,用lambda(λ)来声明匿名函数,这种匿名函数是没有名字的,是临时使用的

好处:

  • Python写一些执行脚本时,使用lambda就可以省下定义函数过程,比如说我们只是需要写个简单的脚本来管理服务器时间,我们就不需要专门定义一个函数然后再写调用,使用lambda就可以使得代码更加精简。
  • 对于一些比较抽象并且整个程序执行下来只需要调用一两次的函数,有时候给函数起个名字也是比较头疼的问题,使用lambda就不需要考虑命名的问题了
  • 简化代码的可读性,由于普通的屌丝函数阅读经常要跳到开头def定义部分,使用lambda函数可以省去这样的步骤。

格式:

函数对象名 = lambda 形式参数:表达式

eg15:

def add(x,y=3):
    return x+y

add(1,2)

结果为
3


用lambda匿名函数可以一步到位
eg16:

fun1 = lambda x,y=3: x+y

调用和 def 定义的函数一样

fun1(1,2)

output

3

以上,用匿名函数代替了add()函数的功能
x,y是形式参数
x+y 是函数体内容


再来个例子熟悉下
eg17:

#匿名函数也可以有条件分支语句,返回x和y中较大值
find_max = lambda x,y: x if x>=y else y

调用

find_max(1,2)

结果为
2

小建议:当函数较为复杂时,不建议匿名函数,不太好写而且结构难理解


7 函数的递归

递归指的是一种直接或者间接调用自身的算法,它的本质是将问题分解为同类型的子问题。注意与迭代的区别。

以等比数列为例(首项为1,公比为2),看看函数的递归
eg18:

def dengbi(x):
    if x == 1:
        return x
    else:
        return 2*dengbi(x-1)

调用

dengbi(10)

结果为
512


再看看斐波拉希数列
eg19:

def Fibonacci(x):
    if x == 0:
        return 0
    elif x == 1:
        return 1
    else:
        return Fibonacci(x-2)+Fibonacci(x-1)

调用

Fibonacci(10)

结果为55

8 链式函数调用

在第一行调用多个函数

def add(x,y):
    return x + y

def sub(x,y):
    return x - y

x,y = 3,4
print((add if x > y else sub)(x,y))

x,y = 4,3
print((add if x > y else sub)(x,y))

output

-1
7

附录

global

函数无法修改全局变量

string = "string"

def do_nothing():
  string = "inside a method"

do_nothing()

print(string)  # string

通过 global 可以修改

string = "string"

def do_nothing():
    global string
    string = "inside a method"

do_nothing()

print(string)  # inside a method
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值