Python集训营45天—Day04 (函数)

系统 1507 0

目录

  • 1. 函数介绍
  • 2. 函数的参数
  • 3. 模块与函数
  • 4. 递归函数
  • 5. 匿名函数
  • 6. 多返回值

python 的学习已经进入到第四天,前面几章我们已经学会了基本的变量操作,以及分支结构和循环结构,那么本章,我们来说说 python 中的函数

1. 函数介绍

在开发程序中,如果需要调用某段代码多次,但是为了 提高编写的效率以及代码的可重用性,所以把具有独立功能的代码块 组织成一个独立的小模块,这就是函数。

在Python 中可以使用 def 关键字来定义函数,和变量一样每个函数也需要声明一个符合命名规范的名称。在函数后面的圆括号内可以放置我们需要传递的参数,待结果执行完毕我们也可以根据需要 使用 return 关键字返回调用结果。

 

案例:

我们先看一道数学题

事实上,上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案。想到这一点问题的答案就呼之欲出了。

如果我们还没有学过函数,我们可以这么写

          
            """
输入M和N 计算C(M,N)
version:0.1
author:coke
"""
m = int(input('m='))
n = int(input('n='))
fm = 1
for x in range(1,m + 1):
    fm *= x
fn = 1
for y in range(1,n + 1):
    fn *= y
fmn = 1
for z in range(1,m - n + 1):
    fmn *= z
print(fm // fn // fmn)
          
        

 

你应该发现了,相似的for循环我们写了三遍,我们是不是可以做一个提取呢?

          
            """
用函数求分配方案
version: 0.1
author: coke
"""
#-*- coding:utf-8 -*-
def factorial(num):
    """
        求阶乘
        :param num 非负整数
        :return num的阶乘
    """
    result = 1
    for n in range(1, num + 1):
        result *= n
    return result

m = int(input("请输入一个数字m:"))
n = int(input("请输入一个数字n:"))
print(factorial(m)//factorial(n)//factorial(m-n))
          
        

 

2. 函数的参数

函数是绝大多数编程语言中都支持的一个代码的“构建块”,但是Python中的函数与其他语言中的函数还是有很多不太相同的地方,其中一个显著的区别就是Python对函数参数的处理。在Python中,函数的参数可以有默认值,也支持使用可变参数,所以Python并不需要像其他语言一样支持函数的重载 。所以我们定义一个函数时,可以让它有很多不同的使用方式.

          
            from random import randint
def roll_rice(n = 2):
    """
        :param n:色子数
        :return: n颗色子的点数和
    """
    total = 0
    for _ in range(n):
        total += randint(1,6)
    return total
def add(a ,b = 0 ,c=0):
    return a + b + c


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

我们给上面两个函数的参数都设定了默认值,这也就意味着如果在调用函数的时候如果没有传入对应参数的值时将使用该参数的默认值,所以在上面的代码中我们可以用各种不同的方式去调用 add 函数,这跟其他很多语言中函数重载的效果是一致的。

其实上面的add 函数还有更好的实现方法,因为我们可能会 对 0个或多个参数进行加法运算,而具体有几个参数完全可以由调用者决定

          
            #-*-coding:utf-8-*-
# 在参数名前面的*表示args是一个可变参数
# 即在调用add函数时可以传入0个或多个参数
def add(*args):
    total = 0
    argsType = type(args)
    print("args的类型为:%s"%argsType)
    for val in args:
        total += val
    return total

print(add())
print(add(1))
print(add(1,2))
print(add(1,2,3))
          
        

 

3. 模块与函数

对于任何一种编程语言来说,给变量、函数这样的标识符起名字都是一个让人头疼的问题,因为我们会遇到命名冲突这种尴尬的情况。最简单的场景就是在同一个.py文件中定义了两个同名函数,由于Python没有函数重载的概念,那么后面的定义会覆盖之前的定义,也就意味着两个函数同名函数实际上只有一个是存在的。

          
            """
测试代码
version:0.1
author:coke
"""
def foo():
   print("hello-world")

def foo():
   print("world-hello")
#下面的代码会输出什么? 是不是有点混乱
foo()
          
        

 

当然上面的这种情况我们很容易就能避免,但是如果项目是由多人协作进行团队开发的时候,团队中可能有多个程序员都定义了名为 foo 的函数,那么怎么解决这种命名冲突呢?答案其实很简单,Python中每个文件就代表了一个模块(module),我们在不同的模块中可以有同名的函数,在使用函数的时候我们通过 import 关键字导入指定的模块就可以区分到底要使用的是哪个模块中的 foo 函数,代码如下所示

module1.py

          
            def foo():
    print("hello-world")
          
        

module2.py

          
            def foo():
    print("world-hello")
          
        

moduleTest1.py

          
            import module1 as m1
import module2 as m2
#输出 hello-world
m1.foo()
#输出 world-hello
m2.foo()

          
        

 

但是如果将代码写成了下面的样子,那么程序中调用的是最后导入的那个 foo ,因为后导入的foo覆盖了之前导入的 foo

moduleTest2.py

          
            from module1 import foo
from module2 import foo

# 输出goodbye, world!
foo()
          
        

 

需要说明的是,如果我们导入的模块除了定义函数之外还中有可以执行代码,那么Python解释器在导入这个模块时就会执行这些代码,事实上我们可能并不希望如此,因此如果我们在模块中编写了执行代码,最好是将这些执行代码放入如下所示的条件中,这样的话除非直接运行该模块,if条件下的这些代码是不会执行的,因为只有直接执行的模块的名字才是 '__main__'

          
            def foo():
   pass
def bar():
   pass

# _name_ 是Python中一个隐含的变量它代表了模块的名字
# 只有被python解释器直接执行的模块的名字是 __main__
if __name__ == '__main__':
   print('call foo')
   foo()
   print("call bar")
   bar
          
        

 

4. 递归函数

递归函数: 如果一个函数在内部不调用其它的函数,而是自己本身的话,这个函数就是递归函数。

 

举个例子:我们来计算阶乘  n! = 1 * 2 * 3 * ... * n

方案1: 循环解决

          
            """
while 循环算阶乘
version:0.1
author:coke
"""
# -*- coding:utf-8 -*-
def calNum(num):
    i = 1
    result = 1
    while i <= num:
        result *= i
        i += 1
    return result

total = calNum(4)
print(total)
          
        

 

方案2: 递归函数

          
            """
while 循环算阶乘
version:0.1
author:coke
"""
# -*- coding:utf-8 -*-
def calNum(num):
    if num > 1:
        result = num * calNum(num - 1)
    else:
        result = 1
    return result

total = calNum(4)
print(total)
          
        

 

5. 匿名函数

lambda 关键词能创建小型匿名函数。这种函数得名于省略了用 def 声明函数的标准步骤。

lambda 函数的语法只包含一个语句,如下:

          
               lambda [arg1 [,arg2,.....argn]]:expression
          
        

 

1. 使用匿名函数求两数之和 (自己定义函数 )

          
            """
匿名函数测试
version:0.1
author:coke
"""
def add(a,b):
    return a+b

result1 = add(1,6)
# 使用lambda 表达式
sum = lambda  x,y: x+y
result2 = sum(1,6)
print(result1)
print(result2)
          
        

 

2. 数据排序 (作为内置函数的参数 )

          
            """
匿名函数作为内置函数进行排序
关于 字典和列表的知识点后面会讲
version:0.1
author:coke
"""
stus = [
    {"name":"zhangsan", "age":18}, 
    {"name":"lisi", "age":19}, 
    {"name":"wangwu", "age":17}
]
stus.sort(key = lambda x:x['name'])
print(stus)
          
        

 

6. 多返回值

在python中 一个函数可不可以返回多个 返回值呢?

          
            """
多返回值的测试
version:0.1
author:coke
"""
def cal(a,b):
    add = a+b
    mul = a*b
    return add,mul

result = cal(2,3)
print(result)
          
        

输出结果

 

一个函数,返回多个返回值 ,本质上是利用了元组的特性。

注:关于元组,列表,字典的知识点后面会讲,这里先提一嘴。


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论