一、简介

当我们发现有一些代码块需要随时需要使用,而且可能会重复使用,那么如何写出精简,不冗余的高质量代码呢—使用函数封装成一个函数方法?

函数:是组织好的,可重复使用的,用来实现单一,或相关联功能的代码块。
函数能提高应用的模块性,和代码的重复使用率。
如我们前面使用的print() 、range()函数,但你也可以自己创建函数,这被叫做用户自定义函数。

二、函数的定义

你可以定义一个由自己想要功能的函数,以下是简单的规则:

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()
  • 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
  • 函数内容以冒号起始,并且缩进
  • return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
    1. def functionname( parameters ):
    2. function_suite
    3. return [expression]
    默认情况下,参数值和参数名称是按函数声明中定义的顺序匹配起来的。

    三、函数的调用

    ```python

    定义函数

    def printme( str ): print str return

调用函数

printme(“我要调用用户自定义函数!”) printme(“再次调用同一函数”)

  1. <a name="uPNfy"></a>
  2. ## 四、参数
  3. 调用函数时可使用的正式参数类型:
  4. - 位置参数
  5. - 关键字参数
  6. - 默认参数
  7. - 不定长参数
  8. <a name="yEVrB"></a>
  9. ### 位置参数/必传参数
  10. 位置参数须以正确的顺序传入函数。调用时的数量和顺序必须和声明时的一样。
  11. ```python
  12. def fun01(num1, num2):
  13. print("num1:", num1)
  14. print("num2:", num2)
  15. total = num1 + num2
  16. print("{}+{}={}".format(num1, num2, total))
  17. fun01(1, 2)

调用fun01()函数,你必须传入2个参数,不然会出现语法错误:

fun01(1)

Traceback (most recent call last):
  File "D:/MyWorkStation/PythonProject/python_100/test.py", line 8, in <module>
    fun01(1)
TypeError: fun01() missing 1 required positional argument: 'num2'

关键字参数

关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。
以下实例在函数 fun02() 调用时使用参数名:

def fun02(num1, num2):
    print("num1:", num1)
    print("num2:", num2)
    total = num1 + num2
    print("{}+{}={}".format(num1, num2, total))


fun02(num2=1, num1=2)

默认参数

调用函数时,默认参数的值如果没有传入,则被认为是默认值。下例中如果num2没有被传入,会使用num2默认的值:

def fun02(num1, num2=5):
    print("num1:", num1)
    print("num2:", num2)
    total = num1 + num2
    print("{}+{}={}".format(num1, num2, total))


fun02(1, 3)
fun02(1)

输出结果:

num1: 1
num2: 3
1+3=4
num1: 1
num2: 5
1+5=6

不定长参数/可变参数

你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述2种参数不同,声明时不会命名。基本语法如下:

args:接收到的所有按照必传参数方式传递进来的参数,是一个元组类型
*
kwargs:接收到的所有按照关键字参数方式传递进来的参数,是一个字典类型

def fun02(*args):
    print(type(args))
    print(args)


fun02(2, 3, 4)

我们执行上面代码会打印一个元组(2,3,4)出来 ,相等于 传了多个参数他会把这多个参数装进一个元组传进去 如果你想取任意一个值 只需要取对应索引

def fun03(**kwargs):
    print(type(kwargs))
    print(kwargs)


fun03(a=1, b=3)

**kwargs 我们可以看到 我们必须要传一个 一对参数进去 键值 键和值都可以自定义

参数定义时的顺序

当定义一个函数时有多种参数时:位置参数,默认参数,不定长参数
位置参数在前,然后默认参数,最后不定长参数

五、匿名函数

python 使用 lambda 来创建匿名函数。

  • lambda只是一个表达式,函数体比def简单很多。
  • lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
  • lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。
  • 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。

    语法

    lambda函数的语法只包含一个语句,如下:
    lambda [arg1 [,arg2,…..argn]]:expression

匿名函数的定义与使用:

# 普通函数的定义
def sum01(num1, num2):
    print("调用方法sum01:", num1 + num2)


# 匿名函数定义
sum02 = lambda num1, num2: print("调用方法sum02:", num1 + num2)

# 调用普通函数sum01
sum01(10, 20)
# 调用匿名函数sum02
sum02(10, 20)

六、返回值:return

return语句[表达式]退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。之前的例子都没有示范如何返回数值,下例

def sum01(num1, num2):
    print("调用方法sum01:", num1 + num2)
    return


def sum02(num1, num2):
    total = num1 + num2
    return total


print(sum01(1, 2))
print(sum02(1, 2))

七、变量作用域

一个程序的所有的变量并不是在哪个位置都可以访问的。访问权限决定于这个变量是在哪里赋值的。
变量的作用域决定了在哪一部分程序你可以访问哪个特定的变量名称。两种最基本的变量作用域如下:

  • 全局变量
  • 局部变量

八、全局变量和局部变量

定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。
局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。如下实例:

total = 0  # 这是一个全局变量


def sum(arg1, arg2):
    total = arg1 + arg2  # total在这里是局部变量.
    print("函数内是局部变量 : ", total)
    return total


# 调用sum函数
sum(10, 20)
print("函数外是全局变量 : ", total)

练习:
1.定义一个函数 求两个数之间的和
2.定义一个函数,求三个数的最大值
3.定义一个函数,输入任意三个数字判断是否能构成三角形