我们这两天写的代码都是 写完之后可以直接执行的。在项目中,会有很多代码,比如昨天写了以生成手机号的程序。在注册用户的时候会用到,在登陆的时候也用到。代码需要复用,最好将代码封装起来。封装可以使用函数来进行封装。

基本语法

定义一个函数,可以使用 def 关键字定义。
函数名 跟定义变量的时候的函数名一样:

  1. 不能以数字开头
  2. 不能使用除了 _ 之外其他的特殊字符。

    定义函数

    1. def 函数名():
    2. 具体的代码
    写一个基本的例子,定义函数。
    def say_hello():
     print("你好!")
     print("hello")
     print("hi")
    
    定义函数之后 默认函数不会执行, 只有在调用函数的时候才能执行。

    调用函数

    调用函数,使用函数名()的方式来调用。 ```python

    定义函数

    def say_hello(): print(“你好!”) print(“hello”) print(“hi”)

    调用函数

    say_hello()
![image.png](https://cdn.nlark.com/yuque/0/2022/png/87080/1652843776643-e1f7ada1-d4ae-4b0c-a903-07fcc9062556.png#clientId=ud159d5c9-b5f8-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=362&id=ud8bd6377&margin=%5Bobject%20Object%5D&name=image.png&originHeight=694&originWidth=895&originalType=binary&ratio=1&rotation=0&showTitle=false&size=70963&status=done&style=none&taskId=ua685ef20-d26e-4410-b891-da2668e0fec&title=&width=467)
<a name="lhnxX"></a>
## 实例演习
将昨天定义的生成手机号程序封装到函数中。<br />定义函数名 get_phone()
```python
import random
def get_phone():
    # 定义支持号段
    pre_phones = ["130","131","132","133","134","135","136","137","138","139",
             "170","172","179",
            "150","151","155","156",
            "188",
            "199"]
    # 随机取号段
    pre_3 = random.choice(pre_phones)
    print(f"随机选择号段 {pre_3}")
    # 生成后8位
    last_8 = ""
    for i in range(8):
        随机生成一个数字n
        n = random.randint(0,9)
        # 拼接字符串 将n转换为字符串
        last_8 = last_8+str(n) # 每次随机取到一个数字,转换字符串之后 放到last_8 后面
    print(f"生成后8位 {last_8}")
    # 将前3位后8位 组合一起
    phone = pre_3 + last_8
    print(f"生成手机号 {phone}")

get_phone()

调用函数。可以看到结果。

随机选择号段 179
生成后8位 16355453
生成手机号 17916355453

总结: 定义函数可以将一些常用的代码封装起来。可以实现复用。

函数的返回值

在python的基本数据类型中 None 表示没有。
定义函数,没有设置返回值, 函数的结果None

def f1():
    a = 10

f = f1()
print(f) # None

定义函数,主要为了代码复用,只需要调用函数名就可以执行函数中的代码。函数也有运算结果。定义多个函数。 函数之间可以进行调用。

return关键字

如果函数1的运算结果,需要在函数2中使用,这个时候需要添加返回值。(这个返回值类似 我们在做接口的时候上下游传参,将上游的接口中的结果传递给下游)
函数基础🎈 - 图1

def get_phone():
    phone = "1321113223"
    # 将phone return 出去
    return phone


def register():
    # 注册用户需要使用手机号
    phone = get_phone() # 拿到
    print(f"使用手机号 {phone} 进行注册")

register()

执行,可以看到 在register 中可以使用到 get_phone 中返回的结果。
image.png

是否使用 return 返回值,取决于别的函数中需不需要用到这个函数中的结果,如果用到这个结果,那就返回出去。
函数中return的数据 可以是任意类型。

  • 数字
  • 字符串
  • 列表
  • 元组
  • 字典
  • 集合
  • 布尔 True False

    使用

    ```python import random def get_phone():

    定义支持号段

    pre_phones = [“130”,”131”,”132”,”133”,”134”,”135”,”136”,”137”,”138”,”139”,
           "170","172","179",
          "150","151","155","156",
          "188",
          "199"]
    

    随机取号段

    pre_3 = random.choice(pre_phones)

    print(f”随机选择号段 {pre_3}”)

    生成后8位

    last_8 = “” for i in range(8):
      n = random.randint(1,9)
      # 拼接字符串
      last_8 = last_8+str(n)
    

    print(f”生成后8位 {last_8}”)

    将前3位后8位 组合一起

    phone = pre_3 + last_8

    print(f”生成手机号 {phone}”)

    将结果返回

    return phone

def register():

# 注册用户需要使用手机号
phone = get_phone() # 调用 函数,可以拿到函数的返回值
print(f"使用手机号 {phone} 进行注册")

def login(): p = get_phone() print(f’使用手机号 {p} 进行登录’)

调用函数

register() login()


---

如果你要返回很多值。 可以将很多数据放在列表中 或者字典中放回 ,也可以是元组中。
```python


import random
def sj():
    nums = []
    for i in range(3):
        nums.append( random.randint(1,10))

    return nums


print(sj()) # [2, 3, 4]
def sj2():
    a1 = random.randint(1,10)
    a2 = random.randint(10,20)
    a3 = random.randint(20,30)
    return [a1,a2,a3]

print(sj2()) # [6, 16, 22]
def sj3():
    a1 = random.randint(1,10)
    a2 = random.randint(10,20)
    a3 = random.randint(20,30)
    return (a1,a2,a3)  # 元组

print(sj3())

def sj4():
    a1 = random.randint(1,10)
    a2 = random.randint(10,20)
    a3 = random.randint(20,30)
    return {a1,a2,a3}  # 集合

print(sj4()) # {11, 27, 3}


def sj5():
    a1 = random.randint(1,10)
    a2 = random.randint(10,20)
    a3 = random.randint(20,30)
    return {0:a1,10:a2,20:a3}

print(sj5())  # 字典

返回结果可以是任意类型, 具体要返回什么类型,根据你的需要,就像在做接口上下游传参的时候你要传递什么值,根据自己的业务。

函数中有返回值的时候的只能有一个return。

def f():
    return 10
    return 20   # 上面已经有return 下面这个就不会执行

print(f()) # 10

函数的参数

调用函数的时候,也可以添加一些参数。比如下面这个函数可以生成10个随机数

import random
def fnum():
    nums = []
    for i in range(10):
        nums.append(random.randint(1,10))

    return nums

nums = fnum()
print(nums)

如果想让这个函数更加灵活一点, 可以生成指定的个数。 for i in range(10): 这个10 更改一下就可以。

设置必填参数

可以在定义函数的时候,添加参数

import random
def fnum(n):
    nums = []
    for i in range(n):
        nums.append(random.randint(1,10))

    return nums

# nums = fnum()
# print(nums) # [1, 10, 6, 1, 9, 2, 3, 2, 4, 9]
# 再次调用 需要传入一个具体的值
nums = fnum(3)
print(nums) # [9, 3, 8]
nums2 = fnum(5)
print(nums2) # [6, 2, 5, 6, 8]

如果函数中定义的时候有参数,比如上面定义了一个 参数n 在调用的时候 fnum() 必须要传入一个值。 fnum(3) 3 就会传给 n。


定义一个函数,可以根据传入的名字,打印一句 问候语。

# 定义函数
def say_hi(name):
    print(f"你好! {name}")

# 调用函数
say_hi("小明") # 你好! 小明
say_hi("Tome") # 你好! Tome

上面函数 定义的时候 有参数,如果调用不传参数 或者传入的参数超过了定义参数个数,都会报错。
image.png
如果传的参数过多,也会报错。
image.png

参数个数

根据需要,可以多个参数。
定义一个 有两个参数的函数。

# 定义函数
def say_welcome(name,word):
    print(f"热烈欢迎 {name}, {word}")

# 调用函数
say_welcome("小王","乘坐本次列车") # 热烈欢迎 小王, 乘坐本次列车
say_welcome("王总","指导工作") # 热烈欢迎 王总, 指导工作
  • name,word 为参数名,类似于变量名,名字可以随意命名。需要注意,函数体中使用的时候要保持一致。

参数的默认值

在定义函数的时候,添加参数,也可以指定参数的默认值。



def myself(city):
    print(f"我在{city}")

myself("上海") # 我在上海
myself("南京") # 我在南京

我们大部分同学都在上海,可以将city的值设置默认值,默认为上海

def myself(city="上海"):
    print(f"我在{city}")


# 函数有默认值,调用的时候,可以不传参,不传参的时候会使用默认值
myself() # 我在上海

# 调用
myself("上海") # 我在上海
myself("南京") # 我在南京

当函数有必填参数,又有默认参数的时候,在定义时,需要注意

  1. 参数的顺序:
    1. 必填参数的位置在前面,有默认值的参数位置 在后面。

下面定义函数,有3个参数

  • name 用户名 必填
  • age 年龄 必填
  • city 城市 有默认值 ```python def to_me(name,age, city=”上海”): print(f”我的名字是{name},今年{age}岁,我在{city}工作”)

调用函数

to_me(“小明”,25) # 我的名字是小明,今年25岁,我在上海工作 to_me(“老王”,60,”毛里求斯”) # 我的名字是老王,今年60岁,我在毛里求斯工作


当参数比较多的时候,有很多默认值。
```python

def to_you(name,age=18,sex="未知",city="上海"):
    print(f"我的名字是{name},性别:{sex},年龄:{age},来自{city}")

to_you("小明") # 我的名字是小明,性别:未知,年龄:18,来自上海
# 因为函数有三个默认值,我只想改 sex  其余使用默认值 传参的时候指定参数
to_you("小王",sex="男") # 我的名字是小王,性别:男,年龄:18,来自上海
# 也可以传参的时候都指定参数名,可以不用考虑参数的顺序 但是name 必须要传值(name是必填的)
to_you(city="阿联酋",name="小往") # 我的名字是小往,性别:未知,年龄:18,来自阿联酋

传参的时候, 可以指定参数名。 如果没有指定参数名,还是按照位置传参。
需要注意的是: 必填参数 一定要传值。


使用函数。

  1. 注意函数的参数, 参数可以有多个
  2. 参数分为必填参数,有默认值的参数
  3. 调用函数的时候,可以指定参数名进行传参,也可以按照顺序进行传参。

函数基础🎈 - 图5


练习

python中我们使用过 print, open, input 这些内置函数,可以直接在python中调用。
image.png
使用 random,可以代码提示 看到传的参数。
image.png
根据需求改造如下函数
这个函数可以生成 5个 随机值

import random

def f_nums():
    nums = []
    for i in range(5):
        nums.append(random.randint(1,10))
    return nums

n1 = f_nums()
print(n1) # [8, 2, 1, 7, 7]
  1. 改造此函数,通过添加参数n,函数在调用的时候,通过传n的值生成,n个随机的数字。 ```python import random

def f_nums(n): “”” 生成指定个数随机数字

:param n: 指定个数
:return:
"""
nums = []
for i in range(n):
    nums.append(random.randint(1,10))
return nums

调用的时候,必须传参

n1 = f_nums(10) print(n1) # [4, 1, 5, 9, 3, 2, 1, 8, 3, 2]


2. 改造此函数,设置默认值,默认生成5个随机值。 将n设置默认值 5
```python
import random

def f_nums(n=5):
    """
    生成指定个数数字

    :param n: 指定个数
    :return:
    """
    nums = []
    for i in range(n):
        nums.append(random.randint(1,10))
    return nums
# 调用的时候,有默认值 可以不传参
n0 = f_nums() # 默认 5
print(n0) # [8, 8, 1, 2, 8]
n1 = f_nums(10) # 10 会覆盖 5
print(n1) # [4, 1, 5, 9, 3, 2, 1, 8, 3, 2]
  1. 上面的函数中 生成的随机数字 random.randint(1,10) 生成1-10 之间的数字。改造此函数,调用函数的时候可以指定生成的随机数字的范围。
    • start 随机数字的开始值
    • end 随机数字的结束值 ```python

import random

def f_nums(start,end,n=5): “”” 生成指定个数数字

:param n: 指定个数
:param start: 随机数字的开始值
:param end: 随机数字的结束值
:return:
"""
nums = []
for i in range(n):
    nums.append(random.randint(start,end))
return nums

调用的时候,有默认值 可以不传参

n1 = f_nums(start=1,end=100) print(n1) # [64, 34, 14, 34, 15]

按位置传参 1传给start 20 会传给end

n2 = f_nums(1,20) print(n2) # [5, 3, 3, 5, 13] # n3 = f_nums(start=100,end=1000,n=10) print(n3) # [512, 258, 765, 869, 345, 295, 756, 488, 615, 597]

n4 = f_nums(1,end=100,n=20) print(n4) # [7, 53, 86, 67, 33, 93, 30, 75, 76, 74, 95, 79, 44, 3, 45, 42, 33, 47, 27, 86] ```