五分钟看懂python函数(同Java方法作比较)

今天来学习python函数,对于有java基础的我来说那岂不是手到擒来

既然已经有java基础了,那么首先我想到的就是两个问题

  • python如何定义函数
  • python如何调用函数

 python中如何定义函数,于是我打开了GitHub上骆昊大神的教程

定义如下:

在Python中可以使用def关键字来定义函数,和变量一样每个函数也有一个响亮的名字,而且命名规则跟变量的命名规则是一致的。在函数名后面的圆括号中可以放置传递给函数的参数,这一点和数学上的函数非常相似,程序中函数的参数就相当于是数学上说的函数的自变量,而函数执行完成后我们可以通过return关键字来返回一个值,这相当于数学上说的函数的因变量。

我们来回忆一下Java方法的定义

修饰符 返回值类型 方法名(参数类型 参数名){
    ...
    方法体
    ...
    return 返回值;
}

而Python函数的定义

def 方法名(参数名):

        ...

        方法体

        ...

        return 返回值

 我们可以看到Python中函数的定义比Java中精简了很多

学着这个样子,我们来定义一个函数

def sum(a, b):
    return a + b

嗯....,函数定义确实很简单

接下来我们来调用上面定义的函数:

def sum(a, b):
    return a + b

if __name__ == '__main__':
    print(sum(2, 3))

 控制台输出:

既然我们函数的定义和调用都学会了,那到这我们难道就学会Python的函数了吗?

 我们再将上面的代码修改一下

def sum(a = 3, b = 4):
    return a + b

if __name__ == '__main__':
    print(sum(2, 3))

 什么,函数的形参竟然设置了默认值?

那我们跑一下代码,看一下结果是多少

 结果还是5,那我们换一种调用方式

def sum(a = 3, b = 4):
    return a + b

if __name__ == '__main__':
    print(sum())

控制台输出一下:

        吆西,竟然换成了7,也就是说如果我们调用函数的时候没有给参数传值,那么这种情况函数就会使用在函数定义中设置的默认值,那么我们如果调用的时候既没有给参数传值,定义函数的时候也没有设置默认值呢?

def sum(a, b):
    return a + b

if __name__ == '__main__':
    print(sum())

没错!报错了

 我们发现原来python是可以给函数设置默认值的重点!!!!

        而回到java,java是不能给方法的参数设置默认值的,至于原因,是因为“默认参数”和“方法重载”同时支持的话有二义性的问题,Java可能为了简单就不要“默认参数”了。当然使用“方法重载”可以间接实现”默认参数“的效果。

我们把所有情况都实现一遍

def add(a=0, b=0, c=0):
    """三个数相加"""
    return a + b + c

if __name__ == '__main__':
    print(add())
    print(add(1))
    print(add(1, 2))
    print(add(1, 2, 3))
    # 传递参数时可以不按照设定的顺序进行传递
    print(add(c=50, a=100, b=200))

控制台输出:

好,我们现在已经学会了函数的定义和调用, 下面来练习几个题目

1.实现计算求最大公约数和最小公倍数的函数 

答案:

def gcd(a, b):
    if(a > b):
        a, b = b, a
    for factor in range(a, 0, -1):
        if(a % factor == 0 and b % factor == 0):
            return factor
def lcm(a, b):
    return a * b // gcd(a, b)

if __name__ == '__main__':
    a = int(input('请输入正整数a:'))
    b = int(input('请输入正整数b:'))
    print('%d和%d的最大公约数为%d' % (a, b, gcd(a, b)))
    print('%d和%d的最小公倍数为%d' % (a, b, lcm(a, b)))

控制台输出:

2.实现判断一个数是不是回文数的函数

答案:

def is_palindrome(n):
    temp = num
    total = 0;
    while(temp != 0):
        total = total * 10 + temp % 10
        temp //= 10
    return num == total

if __name__ == '__main__':
    num = int(input('请输入一个整数:'))
    print(is_palindrome(num))

 控制台输出:

通过这两个题我们似乎已经学会了函数的定义和调用,那么我们接下来要学习什么呢?

我们先来写一段代码:

def Print(n):
    print(a)
    print(n)

if __name__ == '__main__':
    a = 10
    Print(20)

 控制台输出一下:

什么,这竟然没有报错,这要是在java妥妥的报错啊!

 究竟是什么情况?

没错,我们接下来要讲的就是python函数变量的作用域

我们再写一段代码:

def foo():
    b = 'hello'

    # Python中可以在函数内部再定义函数
    def bar():
        c = True
        print(a)
        print(b)
        print(c)

    bar()
    # print(c)  # NameError: name 'c' is not defined


if __name__ == '__main__':
    a = 100
    # print(b)  # NameError: name 'b' is not defined
    foo()

控制台输出一下:

        上面的代码能够顺利的执行并且打印出100、hello和True,但我们注意到了,在bar函数的内部并没有定义ab两个变量,那么ab是从哪里来的。

        我们在上面代码的if分支中定义了一个变量a,这是一个全局变量(global variable),属于全局作用域因为它没有定义在任何一个函数中

        在上面的foo函数中我们定义了变量b,这是一个定义在函数中的局部变量(local variable),属于局部作用域,在foo函数的外部并不能访问到它;但对于foo函数内部的bar函数来说,变量b属于嵌套作用域,在bar函数中我们是可以访问到它的。

  bar函数中的变量c属于局部作用域,在bar函数之外是无法访问的。

        事实上,Python查找一个变量时会按照“局部作用域”、“嵌套作用域”、“全局作用域”和“内置作用域”的顺序进行搜索,前三者我们在上面的代码中已经看到了,所谓的“内置作用域”就是Python内置的那些标识符,我们之前用过的inputprintint等都属于内置作用域。 

那么到这里我们会思考一个问题,既然我们在函数中可以访问到全局变量,那么我们是否可以在函数中修改全局变量呢,这在java中是不能实现的!

我们来设计代码:

def foo():
    a = 20
    print(a)

if __name__ == '__main__':
    a = 10
    foo()
    print(a)

控制台输出一下:

嗯?好像不行

难道在python中只能在函数中访问到全局变量,但是却不能改变全局变量吗?

答案是否定的! 

在调用foo函数后,我们发现a的值仍然是10,这是因为当我们在函数foo中写a = 20的时候,是重新定义了一个名字为a的局部变量,它跟全局作用域的a并不是同一个变量,因为局部作用域中有了自己的变量a,因此foo函数不再搜索全局作用域中的a。如果我们希望在foo函数中修改全局作用域中的a,那么代码可以这么写:

def foo():
    global a
    a = 20
    print(a)

if __name__ == '__main__':
    a = 10
    foo()
    print(a)

 控制台输出一下:

成功!

我们可以使用global关键字来指示foo函数中的变量a来自于全局作用域,如果全局作用域中没有a,那么下面一行的代码就会定义变量a并将其置于全局作用域。

同理,如果我们希望函数内部的函数能够修改嵌套作用域中的变量,可以使用nonlocal关键字来指示变量来自于嵌套作用域

我们来设计代码:

def foo():
    a = 10
    def bar():
        nonlocal a
        a = 20
        print(a)
    bar()
    print(a)

if __name__ == '__main__':
    foo()

控制台输出:

 好的,现在我们已经了解了函数参数的作用域的知识,下面这段话送给大家:

        在实际开发中,我们应该尽量减少对全局变量的使用,因为全局变量的作用域和影响过于广泛,可能会发生意料之外的修改和使用,除此之外全局变量比局部变量拥有更长的生命周期,可能导致对象占用的内存长时间无法被垃圾回收。

        通过今天的学习,已经对python中函数的定义和调用,以及函数参数的作用域已经大致了了解,学会了这些东西,在日常使用中,我们就基本可以应付了,这篇文章参考了GitHub上驼昊的python教程,最近我也正通过他的教程来学习python,如果对python感兴趣的同学,可以去GitHub上自行学习,散会!

GitHub - jackfrued/Python-100-Days: Python - 100天从新手到大师

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

再让我学一会吧!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值