Python 笔记 — 函数基础

本文详细介绍了Python中的函数概念,包括函数定义、优点,以及函数、方法和关键字的区别。讲解了函数的参数类型,如位置参数、默认参数、可变参数和关键字参数,并涉及函数嵌套和DRY原则的应用。通过代码示例展示了函数的调用、返回值和参数传递的过程。
摘要由CSDN通过智能技术生成
目录

一、函数

1、定义

将具体功能封装起来,以便在程序的其它地方重复使用。这有助于代码的模块化和可维护性。

2、优势

  • 减少代码的重复性

  • 使代码的可读性更好

3、函数、方法、关键字区别

函数:封装有独立的功能,可以直接调用。后面需要跟()

方法:通过对象调用,主要针对这个对象进行的操作,后面也需要跟()

关键字:是 Python 中的保留词,具有特定的含义和功能。不能将关键字用作标识符(如变量名或函数名)。

4、基本语法

def 函数名():  # defined 定义的意思 
	函数体  # 没有内容使用 pass 占位符,跳过不会报错;缩进一般是四个空格

(1)def 关键词开头,空格之后接函数名称和圆括号(),最后还有一个":"。

(2)def:是固定的,不能变,它就是定义函数的关键字。

(3)空格:为了将 def 关键字和函数名分开,必须空,当然可以空2格、3格或者想空多少都行,但正常还是空1格。

(4)函数名:只能包含字母、下划线和数字且不能以数字开头。虽然函数名可以随便起,但给函数起名字还是要尽量简短,并且要具有可描述性。

def funa():
	print('哈哈哈')

5、调用

函数名()

(1)函数名加小括号就可以调用了,这个时候函数的函数体会被执行。

(2)只有解释器读到函数名()时,才会执行此函数,如果没有这条指令,函数里面即使有10万行代码也是不执行的。

(3)而且这个指令写几次,函数里面的代码就运行几次。

(4)每次调用函数时,函数都会从头开始执行,当这个函数中的代码执行完毕后,意味着调用结束了。

def funa(): 
    print('哈哈哈')
    
funa()

注意:

  • 函数必须先创建才可以使用,该过程称为函数的定义。

  • 函数创建后可以使用,使用过程称为函数的调用。

二、函数返回值

1、定义

函数返回的值被称为返回值,return 函数的返回值返回给了函数名()这个整体。

2、return 作用

(1)return 会给函数的执行者返回值,但是返回的结果不能输出到控制台(也就是不能直接打印出来),需要通过 print 才能打印出来。

  • 如果 return 后面什么都不写,或者函数中没有 return,则返回的结果是 None

  • 如果 return 后面写了一个值,返回给调用者这个值

  • 如果 return 后面写了多个结果,返回给调用者一个 tuple (元组),调用者可以直接使用元组的解构获取多个变量

def funa():
	a = 10
	return a  # 函数执行完之后会有一个结果,就可以用 return 返回出来
funa()  # 不会被打印,函数的调用之后,执行了就会有一个结果
print(funa())  # 10
print(funa())  # 10
  • return 后面可以是元组、列表、字典、函数等任意对象
  • 只要是能够存储多个数据的类型,就可以一次性返回多个数据
  • 如果返回多个值,是以元组的形式返回的。
def funa():
	a = 10
	b = [1, 2]
	c = {'name': 'zs'}
	return a, b, c
fn = funa()
print(fn)  # (10, [1, 2], {'name': 'zs'})
print(type(fn))  # <class 'tuple'>

(2)函数中遇到 return,此函数结束,不再继续执行。

一个函数中可以有多个 return 语句,但是只要有一个 return 语句被执行到,那么这个函数就会结束了,因此后面的 return 没有什么用处。

def funa():
	return 2
	return 3
print(funa())  # 2

3、return 与 print 区别

  • return 之后的语句不执行,print 会一直执行。

  • print 用于输出内容到控制台,仅用于显示信息,不返回值。它不会影响程序的执行流程。

  • return 用于从函数中返回一个值,并终止函数的执行。它会将结果传递回调用函数的地方,可以用于在程序中进行计算和逻辑操作。

三、函数的参数

函数名后面括号里面的就是用来定义参数的。如果有多个参数,就用逗号进行隔开,函数定义了参数,那么调用函数的时候就需要传入参数。

1、分类

1.1、形参

写在函数声明的位置的变量叫形参,形式上的一个完整。定义时小括号中的参数,用来接收参数用的,仅在函数体内有效。

1.2、实参

在函数调用的时候给函数传递的值叫实参。实际执行的时候给函数传递的信息,调用时小括号中的参数,用来传递给函数用的。

函数的传参就是函数将实际参数交给形式参数的过程。

# 参数能够接受任意类型的对象
def funa(name):  # 函数定义时(参数) 这个就是形参
	print('%s你好' % name)
    
funa('张三')  # 函数执行时(参数) 这个就是实参

这个过程就是:-
代码运行到 funa('张三') 开始执行此函数-
同时将字符串 '张三' 这个数据传递给变量 name-
然后执行函数中的代码,如果遇到 name,其实就是使用 '张三' 这个数据

def add(a, b):
	print(a+b)
    
add(2, 3)  # 5 调用带有参数的函数时,需要在小括号中,传递数据

2、位置参数(必备参数)

位置参数是按照参数列表的顺序传递给函数的参数。函数在调用时需要按照定义的顺序传递相应数量的参数。位置参数在函数体内部通过名称访问。

写了几个,就必须要传几个,不然会报错,调用时按照参数的位置顺序,依次赋予参数值。

def funb(a, b):
	result = a - b
	print(result)
    
funb(3, 1)  # 2
funb(3)  # TypeError: funb() missing 1 required positional argument: 'b'

3、默认参数(缺省参数)

默认参数在函数定义时指定一个默认值,如果在函数调用时没有提供相应参数,将使用默认值。默认参数通常在参数列表的末尾定义。

在函数声明的时候,就可以给出函数参数的默认值。默认值参数一般是这个参数使用率较高,才会设置默认值参数。

def funa(a=12):                
	print('%s哈哈哈'%a)           
                               
funa()  # 12 如果没传值,就按默认的参数去执行   
funa(15)  # 15 如果传了值,就按传的参数去执行  

注意: 带有默认值的参数一定要位于参数列表的最后面。

4、不定长参数

有时需要一个函数处理多个数据,这时用到多值参数。

在参数前加一个 * 可以接收元组,加 ** 可以接收字典。

一般用 *args 存放元组参数,用 **kwargs 存放字典参数。

4.1、可变参数

传入的参数数量是可变的,传入的数量可以是任意多个,但也可以没有。

args 就是一个普通的形参,但是如果在 args 前面加一个 *,那么就拥有了特殊的意义,它是有魔法的。

def funa(*args):  # 接收多个值,都是以元组接收的
	print(args)
	print(type(args))

funa(1,2,3)
# 运行结果:
# (1, 2, 3)
# <class 'tuple'>

这样设置形参,那么这个形参会将实参所有的位置参数接收,放置在一个元组中,并将这个元组赋值给 args 这个形参,这里起到魔法效果的是 * 而不是 args,a 也可以达到这个效果,但是 PEP8 规范中规定就使用 args,约定俗成的。

def funa(*a):
	print(a)
	print(type(a))

funa('a', 'b', 'c')
# 运行结果:
# ('a', 'b', 'c')
# <class 'tuple'>
4.2、关键字参数

** kwargs,同理这个 ** 也是具有魔法用法的,kwargs 约定俗成使用作为形参。

** kwargs,是接收所有的关键字参数,然后将其转换成一个字典赋值给 kwargs 这个形参。 关键字参数也允许传入0个或者任意个含参数名的参数,这些关键字参数会在函数内部自动组装为一个 dict。

def funa(**kwargs):  # 关键字传参             
	print(kwargs)                        
	print(type(kwargs))                  
                                         
funa(a='ss',b=12)  # 键等于值的形式             
# 运行结果:                                  
# {'a': 'ss', 'b': 12}                   
# <class 'dict'>                         


def funa(**b):                         
	print(b)                           
	print(type(b))                     
                                       
funa(name='zs', age=18)                
# 运行结果:                                
# {'name': 'zs', 'age': 18}            
# <class 'dict'>                       

5、混合参数

参数定义顺序:-
位置参数(必备参数)、默认参数(缺省参数)、可变参数(*args)、关键字参数(** kwargs)

*args 必须在 **kwargs 前面

如果很多个值都是不定长参数,那么这种情况下,可以将缺省参数放到 *args 的后面, 但如果有 ** kwargs 的话, ** kwargs 必须是最后的。

# 例一:                                                               
def funa(a, b=10, *c):  # 必备 默认 可变                                  
	print(a, b, c)                                                  
                                                                    
funa(1, 2, 3, 4)                                                    
# 运行结果:                                                             
# 1 2 (3, 4)                                                        
                                                                    
# 例二:                                                               
def funb(a, *c, b=20):  # 必备 可变 默认                                  
	print(a, c, b)                                                  
                                                                    
funb(1, 2, 3, 4)                                                    
# 运行结果:                                                             
# 1 (2, 3, 4) 20                                                    
                                                                    
# 例三:                                                               
def func(a, b=20, *c, **d):  # 必备 默认 可变 关键字                                             
	print(c, d)                                                     
	print(a, b)                                                     
                                                                    
func(1, 2, 3, 4, na='as', age=12)                                   
# 运行结果:                                                             
# (3, 4) {'na': 'as', 'age': 12}                                    
# 1 2                                                               

四、函数嵌套

函数的嵌套,就是一个函数中还有函数。

使用嵌套函数的情况

  • 封装 - 数据隐藏

  • 贯彻 DRY 原则,嵌套函数,可以在函数内部避免重复代码。

  • 闭包:闭包、装饰器这些高级用法跟嵌套函数紧密相关。

DRY(Don’t Repeat Yourself)

是指在程序设计以及计算中避免重复代码,因为这样会降低灵活性、简洁性,并且有可能导致代码之间的矛盾。DRY 更多的是一种架构设计思想,在软件开发过程中的万事万物均可能重复,大到标准、框架、开发流程;中到组件、接口;小到功能、代码均存在自我重复。而 DRY 提倡的就是在软件开发过程中应消除所有这些自我重复。

嵌套调用:在一个函数里面调用别的函数。

def funa():                    
	print('这是funa')            
def funb():                    
	print('这是funb')            
	funa()                     
                               
funb()                         
# 运行结果:                        
# 这是funb                       
# 这是funa                       

嵌套定义:在一个函数中定义了另外一个函数。在外函数内部调用内函数,即用函数名调用。

def funa():                  
	def funb():              
		print('这是funb')      
	print('这是funa')          
	funb() # 函数名调用内函数        
                             
funa()                       
# 运行结果:                      
# 这是funa                     
# 这是funb                     

可以用 return 调用内函数

def funa():                      
	print('这是外部函数')              
	def funb():                  
		print('这是内部函数')          
	return funb()                
                                 
funa()                           
# 运行结果:                          
# 这是外部函数                         
# 这是内部函数                         

五、代码练习

1、写一个函数求三个数的和

def calculate_sum(a, b, c):
    total = a + b + c
    return total

num1 = 5
num2 = 10
num3 = 3

result = calculate_sum(num1, num2, num3)
print(f"{num1} + {num2} + {num3} = {result}")  # 5 + 10 + 3 = 18

2、求这个三个数的平均值

def calculate_average(a, b, c):
    total = a + b + c
    average = total / 3
    return average

num1 = 5
num2 = 10
num3 = 3

average_result = calculate_average(num1, num2, num3)
print(f"{num1}, {num2}, {num3} 的平均数是 {average_result}")  # 5, 10, 3 的平均数是 6.0

3、接收n个数字,求这些参数数字的和

# 思路:
# 1.定义函数 
# 2.接收数字,不知道多少个,用 *args 
# 3.计算累积和,需要两个数相加
# 4.传值计算以后,返回结果 
# 5.调用函数,需要 print 输出结果

def calculate_sum(*numbers):
    total = sum(numbers)
    return total

num1 = 5
num2 = 10
num3 = 3

result = calculate_sum(num1, num2, num3)
print(f"{num1} + {num2} + {num3} = {result}")  # 5 + 10 + 3 = 18

num4 = 8
num5 = 12

result_with_more_numbers = calculate_sum(num1, num2, num3, num4, num5)
print(f"{num1} + {num2} + {num3} + {num4} + {num5} = {result_with_more_numbers}")  # 5 + 10 + 3 + 8 + 12 = 38

4、打印自定义行数的横线

def print_horizontal_lines(lines):
    for _ in range(lines):
        print("-----------")

line_count = 3  # 指定行数
print_horizontal_lines(line_count)

5、实现摇骰子的功能,打印N个骰子的点数和

import random

def roll_dice():
    return random.randint(1, 6)  # 随机生成1到6之间的整数,模拟骰子点数

def roll_and_sum_dice(num_dice):
    total_sum = sum([roll_dice() for _ in range(num_dice)])
    return total_sum

num_dice = 3  # 指定骰子数量
result = roll_and_sum_dice(num_dice)
print(f"{num_dice} 个骰子点数和为 {result}")

6、写一个能够让列表从大到小排序的函数

使用 sorted() 函数对列表进行排序,并通过 reverse=True 参数来实现从大到小的排序,去掉 reverse=True 为从小到大的排序。

# 改变原始列表                                                                   
number_list = [5, 3, 9, 1, 7, 2]  # 测试列表         
                                         
number_list.sort(reverse=True)           
print(number_list)  # [9, 7, 5, 3, 2, 1] 


# 不改变原始列表                                             
def sort_descending(numbers):                         
    sorted_list = sorted(numbers, reverse=True)       
    return sorted_list                                
                                                                                            
number_list = [5, 3, 9, 1, 7, 2]  # 测试列表                      
                                                      
sorted_descending = sort_descending(number_list)      
print(number_list)  # [5, 3, 9, 1, 7, 2]              
print(sorted_descending)  # [9, 7, 5, 3, 2, 1]         

7、求出列表里面的最大值和最小值(不用min和max)

def find_min_max(numbers):
    if not numbers:
        return None, None

    min_value = numbers[0]
    max_value = numbers[0]

    for num in numbers:
        if num < min_value:
            min_value = num
        if num > max_value:
            max_value = num

    return min_value, max_value

# 测试列表
number_list = [5, 3, 9, 1, 7, 2]

min_val, max_val = find_min_max(number_list)
print(f"最小值是: {min_val}")
print(f"最大值是: {max_val}")
  • 在函数中使用 return None, None 的语法是为了返回一个元组,其中包含两个 None 值。这样的语法在返回多个值时是一种常见的做法,即使其中某些值可能是 None 或其它特定的默认值。

  • 在上面的示例中,find_min_max 函数可能会遇到传入空列表的情况,此时无法找到最小值和最大值。为了在这种情况下返回明确的结果,使用了 None, None 来表示不存在最小值和最大值。这样,函数的调用者可以根据返回值是否为 None 来判断是否成功找到最小值和最大值。

  • 例如,调用 find_min_max([]) 将返回 (None, None),而调用 find_min_max([5, 10, 3]) 将返回 (3, 10)。

  • 总之,return None, None 是为了在函数中返回一个表示特定情况的元组,其中的值为 None。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值