python基础-函数(函数参数、返回值、执行、传参、作用域、函数名)
前言
!!!注意:本系列所写的文章全部是学习笔记,来自于观看视频的笔记记录,防止丢失。观看的视频笔记来自于:哔哩哔哩武沛齐老师的视频:2022 Python的web开发(完整版) 入门全套教程,零基础入门到项目实战
1. 初识函数
函数就是一大堆代码的集合,这一堆的代码再起个名字。
# 定义函数 def 函数名(): ... # 执行函数 函数名()
def get_info_data(): print("Hello, World") if True: ... else: ...
应用场景:
- 面向过程编程:根据业务逻辑从上到下写代码;
- 函数式编程:用函数来写代码;【增强代码的重用性】 如果有反复代码的时候,选择用函数式编程
2. Python代码发邮件
-
注册邮箱
-
126/163邮箱
需要获取授权码,通过代码发邮件,在发送邮件的时候不要告诉我们的真实账号密码, Python后续使用: - 账号 - 授权码(不是网易邮箱密码)开启POP3/SMTP,系统会给我们一个授权码 - 保存好自己的授权码,不要丢给别人 - 还有一个,是smtp服务器的地址:我的是smtp.126.com -
发邮箱
# 写代码 让代码发邮件 import smtplib from email.mime.text import MIMEText from email.utils import formataddr # 构建邮件内容 msg = MIMEText("这里是内容", "html", "utf-8") msg["From"] = formataddr(("瑾瑜", "发件箱@126.com")) msg["To"] = formataddr(("领导", "收件箱@qq.com")) msg["Subject"] = "测试一下啦" # 发送邮件 server = smtplib.SMTP_SSL("smtp.126.com") server.login("发件箱@126.com", "balabala这是你的授权码") # 账户 授权码 server.sendmail("发件箱@126.com", "收件箱@qq.com", msg.as_string()) # 发件人 收件人 内容(转为string)
3. 函数的参数
3.1 基本使用
# 定义函数 def 函数名(形式参数1, 形式参数2, ...): ... # 执行函数 函数名(实际参数1, 实际参数2, ...)
在执行函数时,有两种方式,第一种是未知传参,第二种是关键字传参
-
位置传参
def my_function(a1, a2, a3): ... my_function(1, 2, 3) -
关键字传参
def my_function(a1, a2, a3): ... my_function(a1=1, a2=2, a3=3) -
两者混合使用
# 位置传参一定要在前面,关键字传参一定要写在后面 def my_function(a1, a2, a3): ... my_function(1, a2=2, a3=3) -
注意:函数要求传入几个参数,你就必须传入几个参数
-
参数可以是任意类型 None bool int str ...
3.2 练习题
-
定义函数,统计字符串中字符a出现的次数
def count_a(a_string: str): number_a = 0 for i in len(a_string): if a_string[i] == "a": number_a += 1 return number_a
3.3 默认参数
def func(a1, a2=1, a3=2): pass fun(9) # a1=9 a2=1 a3=2 fun(9, 10) # a1=9 a2=10 fun(9, 10, 11) # a1=9 a2=10 a3=11 # 注意: 函数定义时设置的默认参数,只能放在后面
3.4 动态参数
# 只能传有限个参数 def func(a1, a2): pass fun(1, 2)
def func(*a1): # 用户传来的参数会被统一打包成元组 print(a1) func(1) func(11, 22, 33) func(1, 2, 3, "com", "cn") func(1, [11, 22, 33], "com", "org")
-
**
def func(**dt): # 自动将数据打包成为字典 print(dt) # 必须用关键字的形式传参 func(a1=1, b1=2, c3="computer") -
* 和 ** 混合使用
def func(*a1, **dt): print(dt) func(11, 22, 3, xx=123, yy=456, zz="com") # a1=(11, 22, 3,) xx={"xx": 123, "yy": 456, "zz": "com"} # 注意事项: # 1. 定义函数的顺序两个*的一定要在一个*的后面 # 2. 执行函数时,位置传参在前,关键传参在后 # 3. 当不传参数时,a1和dt都是空 -
混合之前:
def func(x1, x2, x3, *a1, **dt): print(dt) func(0, 1, 2, 11, 22, 33, xx=123, yy=456, zz="com") -
* 和 ** 支持传入多个参数,自动会将数据打包成元组和字典
-
潜规则: 在定义动态参数的时候,
*args
,**kwargs
4. 函数的返回值
-
print()
是输出语句,和函数返回值没有半毛钱关系 -
函数的返回值:想让函数帮我们实现某个功能,希望给我们一个结果,运行完后产出一个返回值
def func(a, b): res = a + b return res # 执行func函数 # 将函数的返回值赋值给data变量 data = func(1, 2) -
注意事项
def func(): return 11,22,33 # 这种是返回元组 -
如果函数没有任何
return
语句,那么函数默认返回None
-
在函数执行过程中,会立即结束当前函数的的执行并返回
-
返回值的时候,可以只写
return
,如果只写return
,那么还是返回None
4.1 练习题
- 写一个函数
- 判断一个参数1:字符串(文件路径)是否是存在的,
- 不存在则返回None,
- 存在,则读取文件的每一行数据,判断每一行数据是否包含参数2:字符串
- 在,则将这一行数据追加到列表中
- 不在,继续读下一行
- 返回列表,包含字符串的每一行数据
- 最终自己调用这个函数
- 判断一个参数1:字符串(文件路径)是否是存在的,
5. 函数的执行
# 这样会报错 func() def func(): pass
def f1(): print(123) def f2(): print(456) f1() f2() f1()
def f1(): print(123) return 1 def f2(arg): return arg + 10 def f3(arg): print(arg) v1 = f1() # v1 = 1 v2 = f2(v1) # v2 = 101 v3 = f3(v2) # v3 = None
def f1(): print(1) print(2) def f2(): f1() print(999) f2() # 输出: """ 666 1 2 999 """
在数据类型的学习中,有可变和不可变类型
- 字典 列表 集合 ---> 可变类型
- 字符串 字面量 元组 布尔 ---> 不可变类型
6. 函数传参——传递的是内存地址
v1 = "computer" v2 = v1
def func(a1): print(a1) v1 = "computer" func(v1) # 注意:函数在传递参数的时候,默认不会创建一份新数据,再赋值给函数中的参数,而是同时指向同一块内存 # 参数传递的是引用/内存地址
- 注意事项
- 函数参数传递时,传递的是引用/内存地址,不会重新拷贝一份
- 一定要注意传递的参数是不是可变类型的数据
7. 数据是否会混乱
def func(a1): data = a1 + 100 print(data) func(100) func(200) # 假设这两个函数并发执行,会不会出现混乱的情况?
当我们每次执行一个函数的时候,都会为这个执行的进程创建一块内存(调用栈)。
所以即使是两个函数同时(并发)执行,也不会出现混乱的情况。
8. 作用域 —— 这一节有点绕,需要认真掌握!
8.1 作用域基础
-
注意:寻找变量的值的时候,优先去自己的作用域里面去找,自己没有的话,去自己的父级作用域找。
-
一个作用域可以理解成为一个内存区域,只要在这个区域就可以共享这个区域的数据;
-
在Python中,以函数为作用域;执行函数得到时候会创建作用域;
-
Python代码只要一运行,就会有一个全局的作用域;
name = "computer" age = 999 if True: email = "xxx@qq.com" else: gender="男" for i in range(10): pass print(name) print(age) print(email) print(i) name = "computer" def func(): v1 = 100 v2 = 200 v3 = v1 + v2 print(v3) func() # 寻找变量的值的时候,优先去自己的作用域里面去找,自己没有的话,去自己的父级作用域找。 print(v1) # 报错 def f1(): age = 19 print(age) def f2(): print(age) def f3(): txt = "com" data = txt + name print(data) # comcomputer f3() def f4(): txt = "com" name = "puter" data = txt + name print(data) f4() # computer print(name) # computer
8.2 关于变量
-
全局变量
在非函数中定义的变量——一般就是在函数的顶层定义的(不在函数里面定义的) -
局部变量
在函数中定义的变量 -
潜规则:在定义全局变量时,需要大写,多个单词用下划线连接。
NAME = "computer" # 全局变量 def function(): name = "computer" # 局部变量
-
局部变量如果和全局变量如果重名,那么:按照作用域基础讲的准则进行判断!
NAME = "computer" def func(): NAME = "science" print(NAME) print(NAME) # computer func() # science print(NAME) # computer
-
案例:用户注册展示系统
USER_LIST = [] def register(): while True: name = input("输入姓名 >>> ") if name.upper() == "Q": return USER_LIST.append(name) def show_users(): for item in USER_LIST: print(item) def run(): register() show_user() run()
8.3 global关键字
用在函数中,用于表示此变量不是新创建的数据,而是全局变量中的那个数据。
NAME = "computer" def func(): global NAME # 这个NAME指的就是全局变量中的那个NAME NAME = "science" # 将全局变量的值重新赋值为"science" print(NAME) print(NAME) # computer func() # science print(NAME) # science
- 关键点:
- 内部global之后,变量就是全局变量
- 赋值操作:经过赋值操作之后,需要认真分析。
NAME = "computer" def func(): global NAME # 这个NAME指的就是全局变量中的那个NAME NAME.upper() # 将全局变量的值重新赋值为"science" print(NAME) print(NAME) # computer func() # computer print(NAME) # computer
NAME = [11, 22] def func(): global NAME NAME = [33, 44] print(NAME) print(NAME) # [11, 22] func() # [33, 44] print(NAME) # [33, 44]
NAME = [11, 22] def func(): global NAME NAME.append(999) print(NAME) print(NAME) # [11, 22] func() # [11, 22, 999] print(NAME) # [11, 22, 999]
NAME = [11, 22] def func(): NAME.append(999) print(NAME) print(NAME) # [11, 22] func() # [11, 22, 999] print(NAME) # [11, 22, 999]
- 永远适用的一点:
- 找变量的时候,优先去自己的作用域找,找不到去父级作用域找。
9. 函数名就是变量名
name = "computer" age = 18 def func(): print(123) print(456) print(name) print(age) print(func) # <function func at 0x00000196298AB760> func = 123 print(func) # 123
def func(): print(123) data = func print(data) # <function func at 0x000001F66713B760>
- 本质上,函数名就是一个变量,代指一个函数而已。
在python列表中,可以存放各种数据类型;
data = [111, 222, "com", (1,), {"a": 12}]
def func(): return 123 v1 = 999 data_list = [1, 2, "com", v1, func, func()] print(data_list) print(data_list[4]) data_list[4]() # 相当于执行函数func == 就等于 func()
案例:开发xx系统,监控,发送微信报警,短信报警 ...
# 这种是不是太慢了?!! def send_wechat(): print("wechat") def send_email(): print("email") def send_sms(): print("短信") if 达到某种指标: send_wechat() send_email() send_sms()
# 这样是不是更简洁!!! def send_wechat(): print("wechat") def send_email(): print("email") def send_sms(): print("短信") func_list = [send_wechat, send_email, send_sms] if 达到某种指标: for item in func_list: item()
案例:用户管理系统(VIP版本)
基于函数实现用户登录 注册 查看所有用户信息
def register(): ... def login(): ... def show_users(): ... print("welcome to xxx system!") print("1. Register | 2. Login | 3. Show all members") choice = input("please choose a number") choice = int(choice) func_list = [register, login, show_users] func_list[choice - 1]()
写在最后
由于这些笔记都是从typora里面粘贴过来的,导致图片会加载失败,如果想要带图片的笔记的话,我已经上传至github,网址(https://github.com/wephiles/python-foundation-note)如果github上不去的话也可以去我的gitee下载,网址(https://gitee.com/wephiles/python-django-notes)。欢迎大家来下载白嫖哦,最后,如果可爱又善良的你能够给我github点个star,那你将会是这个世界上运气最好的人喔。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本