python-函数基础

1.什么是函数

函数就好比一个盒子,它能封装了一段段逻辑代码,当我们需要重复使用这段逻辑代码,只需要调用这个函数即可,这样不仅仅实现了相同的功能,而且避免了重复造轮子,使得代码美观简洁。

2.为什么需要函数?

在开发的过程中,我们往往有成千上万行代码,而且其中还有很多行代码需要重复利用。为了提高代码的重复利用率和编写代码的整洁性,将代码封装在函数里面,使用的时候直接调用函数即可。总之函数的作用1.减少重复代码; 2.方便后期代码的维护更改; 3.保持代码的一致性(修改逻辑代码,后期的调用也会被改)。

3.函数的定义和调用

3.1 函数的定义

# 函数的定义
def myadd(num1, num2):     # 函数头: def---关键字   myadd---函数名   num1,num2 参数
    """
    这是一个计算两个数的和的函数
    :param num1: 第一个                 # 函数接口,类似于说明书,用来说明函数的作用,参数类型和返回值
    :param num2: 第二个数
    :return: 返回和
    """
    res = num1 + num2     # 函数体 :函数的功能块,业务逻辑
    return res            # 返回语句:将函数处理的结果返回给调用者  关键字return + 值 ,多个值用逗号隔开,如果没有返回语句,默认返回none
"""1. 当我们run一个函数的时候,操作系统将接口给cpu,cpu对硬盘下达指令,将函数从硬盘中调取到内存中;2. 在内存中,函数开始从上到下被执行;3. 首先到了def myadd这一个定义的步骤;    (1)4. 内存就会给这个函数划拨一个空间,用于储存函数接口+函数体;5. 函数名myadd直接指向这个空间存储的内容;6. 以上步骤将函数存放到了内存中(函数真正实现功能并不在这步中,只有调用,这个函数才能实现他的功能)。这个定义步骤中,从上到下解释器只是检测代码的语法是否有问题,而不会去执行这个函数的内容比如:def test():    print(a)# 这里不去调用函数,从上到下检测代码语法,不会报错,但是我们知道这个a是没有定义的,但是并没有报错,总之这只是一个定义步骤"""3.2 函数的调用调用的格式为:函数名(参数)
# 函数的调用
a = myadd(3, 4)
print(a)   # 7

4.函数的参数

4.1 形参和实参

形式参数简称形参,在函数没有调用的时候,它没有任何意义,他必须传入参数,所以也叫必须参数

实际参数简称实参,在函数调用的时候传入,与定义函数的时候传入的形参一一对应, 所以它也叫位置参数

def sum(num1, num2, num3):   num1,num2,num3是形式参数
    result = num1 + num2 + num3
    print(result)# 在函数调用的时候sum(12, 23, 34) #59     12, 23, 34就是实参,在这里,12赋值给了num1, 23赋值给了num2, 34赋值给了num3

4.2 默认参数

在我们定义参数的时候,我们给形参一个默认值,在我们调用函数的时候,如果不给有默认值的形参传入参数,那么这个参数就会采用默认值,当给默认参数传入了值,那么这传入的实参就会覆盖掉默认值

注意,当必须参数与默认参数同时使用的时候,默认参数都是放在必须参数后面

def info(name, age, gender="男"):
    print("姓名:{}, 性别:{}, 年龄:{}".format(name, gender, age))
    print("name的实参是:", name)
    print("age的实参是:", age)
    print("gender的实参是:", gender)

info1 = info("小李", 23)           # 姓名:小李, 性别:男, 年龄:23
# name的实参是: 小李
# age的实参是: 23
# gender的实参是: 男
info2 = info("小梅", 22, "女")    # 姓名:小梅, 性别:女, 年龄:22
# name的实参是: 小梅
# age的实参是: 22
# gender的实参是: 女

4.3  关键字参数

关键字参数是在调用的时候传入的,就是以键值对的方式对必须参数赋值

在之前我们都要求位置参数和必须参数是要一一对应的,但是关键字参数可以打破这种形式

def myadd(num1, num2, num3):
    res = num1 + num2 + num3
    return res

a = myadd(num2=12, num3=43, num1=1)
print(a)  # 56# 关键字参数和位置参数同时被使用的时候,关键字参数必须写在位置参数的后面

 4.4 动态参数

动态参数接受的参数是不确定的,是动态的

# 动态参数
# def test(*args, **kwargs):
"""
* 是关键字,**是关键字
args, kwargs是变量名 
当函数调用的时候,传入的所有多余的位置参数会组合成一个元组,被args接受
当函数调用的时候,传入的所有多余的关键字参数组合成一个字典,被kwargs接受
"""

def test(*args, **kwargs):
    print(args)
    print(type(args))
    print(kwargs)
    print(type(kwargs))
    result = 0
    for i in args:
        # result = i     # 12748
        print(i)
        result += i
    print(result)
test(66, 88, 7374, a = 5, b = 8, c = 90)
# (66, 88, 7374)
# <class ‘tuple‘>
# {‘a‘: 5, ‘b‘: 8, ‘c‘: 90}
# <class ‘dict‘>
# 66
# 88
# 7374
# 7528

几种参数的混合使用

1. 首先必须参数是放在最前面的

def test(a, *args, **kwargs):
    print(a, type(a))     # 66 <class ‘int‘>
    print(args, type(args))   # (88, 7374, 4, 5, 89) <class ‘tuple‘>
    print(kwargs, type(kwargs))  # {‘i‘: 5, ‘b‘: 8, ‘c‘: 90} <class ‘dict‘>

test(66, 88, 7374, 4, 5, 89,  i = 5, b = 8, c = 90)

2. 为动态参数传入列表、元组、字典

def test(*args, **kwargs):
    # print(args, type(args))   # (88, 7374, 4, 5, 89) <class ‘tuple‘>
    print(kwargs, type(kwargs))


# 传入列表
li = [1, 2, 3]
test(li, 888)         # ([1, 2, 3], 888) <class ‘tuple‘>,    将li作为一个整体传给args
li = [1, 2, 3]
test(*li, 888)        # (1, 2, 3, 888) <class ‘tuple‘>,     将li解包成单个元素,再传给args
# 元组类似

# 传入字典
di = {"k1": "v1", "k2": "v2", "k3": "v3"}
test(2, di)     # {} <class ‘dict‘>   kwargs接收的是关键字参数,而di并不是一个关键字参数,他被作为一个整体传给了args
test(2, di=di)  # {‘di‘: {‘k1‘: ‘v1‘, ‘k2‘: ‘v2‘, ‘k3‘: ‘v3‘}} <class ‘dict‘>  di=di作为一个关键字参数传入,而字典di的键值对作为一个整体传给了kwargs
test(2, **di)    # {‘k1‘: ‘v1‘, ‘k2‘: ‘v2‘, ‘k3‘: ‘v3‘} <class ‘dict‘> 将di这个字典中的键值对解包,然后将里面的键值对一一传给kwargs

5. 几种常用的内置函数

# 列出全部内置函数
li = dir(__builtins__)
print(li)
print(len(li))    # 153
# 切片选出内置函数
li2 = li[li.index("abs"):]
for i in li2:
    print(li2.index(i)+1, ">>>", i)

(1)enumerate      返回一个可以遍历的对象

# enumerate
"""
def __init__(self, iterable, start=0): # known special case of enumerate.__init__
Initialize self.  See help(type(self)) for accurate signature. """
"""
enumerate有2个参数,一个是可迭代对象,一个是start=0的默认参数
"""
li = ["小明", "小米", "小亮"]

print(li)    # <enumerate object at 0x000002116E339638>  生成一个对象地址
print(list(enumerate(li)))    # [(0, ‘小明‘), (1, ‘小米‘), (2, ‘小亮‘)]
print(dict(enumerate(li)))    # {0: ‘小明‘, 1: ‘小米‘, 2: ‘小亮‘}

for i, j in enumerate(li, 1):
    print("第{}名,{}".format(i, j))
"""
第1名,小明
第2名,小米
第3名,小亮
"""

(2)  filter 过滤器

# filter() 过滤器
# filter(function=, iterable= ) 它的两个参数function是函数,iterable是可迭代对象
# 过滤,每个可迭代对象去执行函数,符合条件的留下,不符合被删去

def test(x):
    return x > 10


li = [1, 11, 2, 40, 8, 20]
print(filter(test, li))      # <filter object at 0x000001310576EC08>
print(list(filter(test, li)))   # [11, 40, 20]

(3)map

# map  是对每一个可迭代对象去执行函数,是对数据对象的处理,将结果返回
# 它的两个参数有函数和可迭代对象
def func(num):
    return num * 10


li = [1, 2, 3]
print(map(func, li))     # <map object at 0x0000021BBC221D88>
print(list(map(func, li)))   # [10, 20, 30]

(4) zip

# zip  将对象逐一地配对
l1 = ["k1", "k2", "k3"]
l2 = ["v1", "v2", "v3"]
print(zip(l1, l2))    # <zip object at 0x000001EAD16B1148>
print(dict(zip(l1, l2)))    # {‘k1‘: ‘v1‘, ‘k2‘: ‘v2‘, ‘k3‘: ‘v3‘}
print(list(zip(l1, l2)))    # [(‘k1‘, ‘v1‘), (‘k2‘, ‘v2‘), (‘k3‘, ‘v3‘)]

相关推荐