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)

    image-20240130203013106

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 练习题

  1. 定义函数,统计字符串中字符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:字符串
        • 在,则将这一行数据追加到列表中
        • 不在,继续读下一行
      • 返回列表,包含字符串的每一行数据
    • 最终自己调用这个函数

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)

    image-20240221155209060

    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

    image-20240222214433456

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()

image-20240224205908376

案例:开发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,那你将会是这个世界上运气最好的人喔。

posted @   想你时风起  阅读(100)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示