函数

函数: 就是实现某种功能的代码块(对功能的封装)

看完下面这个例子你就会知道为什么要使用函数

#模拟开车
开车的变道过程:向左变道,向右变道
a.没用函数
向左变道
print('看左后视镜')
print('打转向灯')
print('像左打方向盘')
print('加速')
print('回正方向盘')

向右变道
print('看右后视镜')
print('打转向灯')
print('像右打方向盘')
print('加速')
print('回正方向盘')

又向左变道
print('看左后视镜')
print('打转向灯')
print('像左打方向盘')
print('加速')
print('回正方向盘')

又向右变道
print('看右后视镜')
print('打转向灯')
print('像右打方向盘')
print('加速')
print('回正方向盘')

我们发现一只变道下去,重复的代码太多,如果需要减少某个变道过程中的步骤,逐个更改太麻烦
那么我们怎么解决问题?答案是通过函数解决
向左变道:
def zuo_yi():
    print('看左后视镜')
    print('打转向灯')
    print('像左打方向盘')
    print('加速')
    print('回正方向盘')
zuo_yi()
zuo_yi()

向右变道:
def you_yi():
    print('看右后视镜')
    print('打转向灯')
    print('像右打方向盘')
    print('加速')
    print('回正方向盘')
you_yi()
you_yi()

如果需要做重复动作,我们只需要调用这个函数即可.这下你对函数就会有所了解了吧!
总结:
没有函数的问题:
1.执行同样的功能的代码需要重复写很多遍,重复的代码太多.
2.功能需求发生改变的时候,需要更改多处代码

1.函数的定义

(1) 固定格式:
def 函数名(参数):
    函数体

def: 固定关键字

函数名: 标识符:a.字母都小写; b.多个单词用_分开;c.见名之意

参数: 叫形式参数,形参可无,可有,还可以有多个参数,用来从函数外面传递数据给函数

函数体: 实现函数功能的代码块,还可能有return语句

调用函数: 函数名(实际参数) a.函数体只有在调用后才会被执行,不调用不执行; b.函数可以调用多次.

例如:写一个函数打印问候语'hello'
def say_hello():
    print('hello function')
say_hello()    #调用函数        >>>hello function
say_hello()    #可以多次调用    >>>hello function
练习: 写一个函数打印:1, 2, 3, 4, 5, 6, 7, 8, 9, 10.然后调用函数查看结果
def numbers():
    for num in range(1,11):
        print(num, end=' ')
numbers()       #>>>1 2 3 4 5 6 7 8 9 10
(2) 定义函数的步骤:

a. 确定函数功能

b. 根据功能确定函数名

c. 确定参数(看实现这个功能需不需要从外面传值到函数里面,如果要传,确定传几个)

d. 实现函数的功能

e. 确定返回值

2.函数的参数

def 函数名(形参):
    函数体

函数的参数类型可以是任何类型
(1) 没有参数的函数:就是形参没有任何内容
例如:
def say_hello():
    print('hello function')
say_hello()      #>>>hello function
(2) 带一个参数的函数
例如:打印一个指定数的2倍是多少?
def print_num(num):
    print(num * 2)
print_num(5)         # >>>10
print_num(11)        # >>>22
总结:调用带参的函数:a.必须在函数名后面的括号里面传参. b.函数的调用过程就是用实参给形参赋值
(3)带多个参数的函数
例如:写一个函数求三个数的和
def print_sum(num1, num2, num3):    #传多个参数用逗号隔开
    print(num1 + num2 + num3)
print_sum(1, 2, 3)           #>>>6
(4)位置参数:按照实参顺序依次给形参赋值
def print_full_name(first_name,last_name):
    print(first_name + last_name)
print_full_name('han','bo')     #实参会依次传递给形参  >>>hanbo
print_full_name('bo','han')        #  >>>bohan
(5)关键字参数
def print_full_name(first_name,last_name):
    print(first_name + last_name)
print_full_name(last_name = 'bo', first_name = 'han')   #>>>hanbo
(6)默认值
在定义函数的时候可给形参赋一个默认的值,如果实参没有值,则执行形参默认值.
注意:函数调用的时候要保证每一个形参都有值.如果参数有默认值,调用的时候可以不用给这个参数赋值
def add_strt(str1, str2, sep='='):
    print('%s%s%s' % (str1, sep, str2))
add_strt('a', 'n', '+')    #>>>a+n
add_strt('a', 'n')         #>>>a=n
注意注意:如果有默认值的形参,必须放到最后面
def add_strt_1(str1, sep, str2='a'):
    print('%s%s%s' % (str1, sep, str2))
add_strt_1(str1 = 'b', sep = '-')      #>>>b-a
(7)参数是列表
例如:打印一个字符串列表中每个元素的长度
def print_len(str_list):
    for x in str_list:
        print(len(x),end=' ')
strs = ['2323', 'hanbo', 'helloworld']
print_len(strs)    #>>>4  5  10

注意:如果参数是列表,在函数里面修改参数的值,会影响实参对应的列表
def print_len(str_list):
    str_list.append('11')
    for x in str_list:
        print(len(x),end=' ')
strs = ['2323', 'hanbo', 'helloworld']
在函数中对形参操作会影响实参的值(前提是参数是列表)
print_len(strs)    #>>>4  5  10
print(strs)        #>>>['2323', 'hanbo', 'helloworld', '11']

strs_2 = ['han', 'bo']
通过切片\copy,将列表作为实参,对应的形参改变不会影响实参的值(前提是参数是列表)
print_len(strs_2[:])
print(strs_2)
补充:python中变量赋值实质是赋的地址
def print_list(list_1):
    list_1 = ['a', 'b', 'c']
    print(list_1)
names = ['1' , '2', '3']
print_list(names)      #>>>['a', 'b', 'c']
print(names)     #>>>['1', '2', '3']
(8)参数个数不固定
写一个函数,做肉夹馍(打印肉夹馍的材料)
def make_food(*goods):
    print(goods)                    #>>>('鸡蛋', '火腿肠', '里脊肉', '肉松')        
    for x in goods:
        print(x, end=' ')           #>>>鸡蛋 火腿肠 里脊肉 肉松
make_food('鸡蛋','火腿肠','里脊肉','肉松')
make_food('生菜', '辣椒', '番茄')