Python函数的基本使用

来自CloudWiki
Cloud17讨论 | 贡献2020年3月15日 (日) 14:44的版本
跳转至: 导航搜索

函数是什么

函数是一段具有特定功能的、可重用的语句组,通过函数名来表示和调用。

经过定义,一组语句等价于一个函数,在需要使用这组语句的地方,直接调用函数名称即可。

  • 将可能需要反复执行的代码封装为函数,并在需要该功能的地方进行调用,不仅可以实现代码复用,更重要的是可以保证代码的一致性,只需要修改该函数代码则所有调用均受到影响。
  • 设计函数时,应注意提高模块的内聚性,同时降低模块之间的隐式耦合。
  • 例1:生日歌
def happy():
    print("Happy birthday to you!")
def happyTo(name):    
    print("Happy birthday, dear {}!".format(name))

happy( )    
happyTo("Mike")
print()
happyTo("Lily")

函数的使用

函数的使用包括两部分:函数的定义函数的调用。 函数是一种功能抽象。

函数的定义

函数名:可以是任何有效的Python标识符

参数列表:是调用该函数时传递给它的值,可以有零个、一个或多个,当传递多个参数时各参数由逗号分隔,当没有参数时也要保留圆括号。

函数体:是函数每次被调用时执行的代码,由一行或多行语句组成。


  • 函数定义语法:
def <函数名>([参数列表]):
    '''注释'''
    <函数体>
    return <返回值列表>
  • Java2-4.png

如果需要返回值,使用保留字return和返回值 列表。函数可以没有return语句,函数体结束 后会将控制权返回给调用者。


  • 例1:生日歌
def happy():
    print("Happy birthday to you!")
def happyTo(name):    
    print("Happy birthday, dear {}!".format(name))

happy( )    
happyTo("Mike")
print()
happyTo("Lily")

注意事项

  • 函数形参不需要声明类型,也不需要指定函数返回值类型
  • 即使该函数不需要接收任何参数,也必须保留一对空的圆括号
  • 括号后面的冒号必不可少
  • 函数体相对于def关键字必须保持一定的空格缩进
  • Python允许嵌套定义函数
  • 设计函数时,应注意提高模块的内聚性,同时降低模块之间的隐式耦合。

例:两点间距离公式常用于函数图形内求两点之间距离、求点的坐标的基本公式,是距离公式之一。两点间距离公式叙述了点和点之间距离的关系。‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬

设两个点A、B以及坐标分别为Python10-1003.png,则A和B两点之间的距离为:‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬

Python10-1002.png ‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬

请输入4个数字(用空格分隔),分别表示x1、y1、x2、y2, 计算距离(保留2位小数输出)。‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬

参考编程模板,参考输入输出示例,完善程序。

输入输出示例

 	输入 	输出
示例 1 	1 2 3 4 	2.83
示例 2 	1 1 2 2 	1.14

函数的调用

通过函数名调用函数功能,对函数的各个参数赋予实际值,称为函数的调用。

实际值可以是实际数据,也可以是在调用函数前已经定义过的变量。

  • 程序调用一个函数需要执行以下四个步骤。
1.调用程序,在调用处暂停执行。
2.在调用时将实参复制给函数的形参。
3.执行函数体语句。
4.函数调用结束后给出返回值,程序回到调用前的暂停处,继续执行。
  • 例1:生日歌;例2:汇率计算器
  • 问题解决:编写生成斐波那契数列的函数并调用。
  • Java2-4.png
  • 在定义函数时,开头部分的注释并不是必需的,但如果为函数的定义加上注释的话,可以为用户提供友好的提示。
  • P5-1.png

例2:汇率计算器

def DolConvert(Num):
    Num =eval(Num);
    Dollar =Num /6;
    return Dollar
    
            
Num = input("请输入人民币值: ")
result = DolConvert(Num)
print("能兑换的美元为:",result)

函数返回

函数执行结束后,根据return保留字的指示决 定是否返回结果,如果返回结果,则结果将被放置到函数被调用的位置,函数使用完毕,程序继续运行。

关于return语句

  • 在Python中,定义函数时也不需要声明函数的返回值类型,而是使用return语句结束函数执行的同时返回任意类型的值,函数返回值类型与return语句返回表达式的类型一致。
  • 不论return语句出现在函数的什么位置,一旦得到执行将直接结束函数的执行。

例如:

def haha(x,y):
    if x==y:
        return x
print(haha(1,1))

12345 2、但是也并不意味着一个函数体中只能有一个return 语句,例如:


def test_return(x):
    if x > 0:
        return x
    else:
        return 0
print(test_return(2))
  • 如果函数没有return语句、有return语句但是没有执行到或者执行了不返回任何值的return语句,解释器都会认为该函数以return None结束,即返回空值。

例如:

def haha(x,y):
    if x==y:
        print(x)
haha(1,1))

函数可以返回多个值吗?答案是肯定的。

比如在游戏中经常需要从一个点移动到另一个点,给出坐标、位移和角度,就可以计算出新的坐标:

import math

def move(x, y, step, angle=0):
    nx = x + step * math.cos(angle)
    ny = y - step * math.sin(angle)
    return nx, ny

import math语句表示导入math包,并允许后续代码引用math包里的sin、cos等函数。

然后,我们就可以同时获得返回值:

>>> x, y = move(100, 100, 60, math.pi / 6)
>>> print(x, y)
151.96152422706632 70.0

但其实这只是一种假象,Python函数返回的仍然是单一值:

>>> r = move(100, 100, 60, math.pi / 6)
>>> print(r)
(151.96152422706632, 70.0)

原来返回值是一个tuple!但是,在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值,所以,Python的函数返回多值其实就是返回一个tuple,但写起来更方便。

参考文档:https://www.liaoxuefeng.com/wiki/1016959663602400/1017106984190464

函数的高级用法(可选)

函数嵌套定义

  • Python允许函数的嵌套定义,在函数内部可以再定义另外一个函数。
>>> def myMap(iterable, op, value):     #自定义函数
   if op not in '+-*/':
       return 'Error operator'
   def nested(item):                   #嵌套定义函数
       return eval(repr(item)+op+repr(value))
   return map(nested, iterable)        #使用在函数内部定义的函数
>>> list(myMap(range(5), '+', 5))       #调用外部函数,不需要关心其内部实现
[5, 6, 7, 8, 9]
>>> list(myMap(range(5), '-', 5))
[-5, -4, -3, -2, -1]
def f2(n,i):
    cache2 = dict()
    
    def f(n,i):
        if n==i or i==0:
            return 1
        elif (n,i) not in cache2:
            cache2[(n,i)] = f(n-1, i) + f(n-1, i-1)
        return cache2[(n,i)]
    
    return f(n,i)
  • 使用标准库提供的缓冲机制进行改写和优化。
from functools import lru_cache

@lru_cache(maxsize=64)
def cni(n, i):
    if n==i or i==0:
        return 1
    return cni(n-1, i) + cni(n-1, i-1)

可调用对象

  • 函数属于Python可调用对象之一,由于构造方法的存在,类也是可调用的。像list()、tuple()、dict()、set()这样的工厂函数实际上都是调用了类的构造方法。另外,任何包含__call__()方法的类的对象也是可调用的。
  • 下面的代码使用函数的嵌套定义实现了可调用对象的定义:
def linear(a, b):
    def result(x):              #在Python中,函数是可以嵌套定义的
        return a * x + b
    return result               #返回可被调用的函数
  • 下面的代码演示了可调用对象类的定义:
class linear:
    def __init__(self, a, b):
        self.a, self.b = a, b
    def __call__(self, x):         #这里是关键
        return self.a * x + self.b
  • 使用上面的嵌套函数和类这两种方式中任何一个,都可以通过以下的方式来定义一个可调用对象:
taxes = linear(0.3, 2)
  • 然后通过下面的方式来调用该对象:
taxes(5)

修饰器

  • 修饰器(decorator)是函数嵌套定义的另一个重要应用。修饰器本质上也是一个函数,只不过这个函数接收其他函数作为参数并对其进行一定的改造之后使用新函数替换原来的函数。
  • Python面向对象程序设计中的静态方法、类方法、属性等也都是通过修饰器实现的。
def before(func):                       #定义修饰器
    def wrapper(*args, **kwargs):
        print('Before function called.')
        return func(*args, **kwargs)
    return wrapper

def after(func):                        #定义修饰器
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        print('After function called.')
        return result
    return wrapper

@before
@after
def test():                             #同时使用两个修饰器改造函数
    print(3)
#调用被修饰的函数
test()