内置方法

列表内置方法

  • 统计数据值的个数:len()
  • 增加数据
    • 尾部追加数据值
      • append():括号内无论写什么数据类型都当成一个数据值追加
      l1 = ['jason', 'kevin', 'oscar', 'tony', 'jerry']
      l1.append('owen')
      print(l1) # ['jason', 'kevin', 'oscar', 'tony', 'jerry', 'owen']
      
    • 任意位置插入数据值
      • insert():括号内无论写什么数据类型都当成一个数据值追加
      l1 = ['jason', 'kevin', 'oscar', 'tony', 'jerry']
      l1.insert(0, '插队')
      print(l1) # ['插队', 'jason', 'kevin', 'oscar', 'tony', 'jerry']
      l1.insert(0, [1, 2, 3])
      print(l1) # [[1, 2, 3], '插队', 'jason', 'kevin', 'oscar', 'tony', 'jerry']
      
    • 扩展列表
      • 方式一:for循环+append()
      new_l1 = [11, 22, 33, 44, 55]
      new_l2 = [1, 2, 3]
      for i in new_l1:
      	new_l2.append(i)
      print(new_l2) # [1, 2, 3, 11, 22, 33, 44, 55]
      
      • 方式二:
      new_l1 = [11, 22, 33, 44, 55]
      new_l2 = [1, 2, 3]
      print(new_l1 + new_l2) # [11, 22, 33, 44, 55, 1, 2, 3]
      
      • 方式三(推荐):expend()(相当于for循环+append())
      new_l1 = [11, 22, 33, 44, 55]
      new_l2 = [1, 2, 3]
      new_l1.extend(new_l2)
      print(new_l1) # [11, 22, 33, 44, 55, 1, 2, 3]
      
  • 查询数据
l1 = ['jason', 'kevin', 'oscar', 'tony', 'jerry']
print(l1) # ['jason', 'kevin', 'oscar', 'tony', 'jerry']
print(l1[0]) # jason
print(l1[1:4]) # ['kevin', 'oscar', 'tony']
  • 修改数据
l1 = ['jason', 'kevin', 'oscar', 'tony', 'jerry']
l1[0] = 'jasonNB'
print(l1) # ['jasonNB', 'kevin', 'oscar', 'tony', 'jerry']
  • 删除数据
    • 通用删除:del 通过索引删除
    l1 = ['jason', 'kevin', 'oscar', 'tony', 'jerry']
    del l1[0]
    print(l1) # ['kevin', 'oscar', 'tony', 'jerry']
    
    • 指名道姓删除:remove 括号内必须填写明确的数据值
    l1 = ['jason', 'kevin', 'oscar', 'tony', 'jerry']
    res = l1.remove('jason')
    print(l1, res) # ['kevin', 'oscar', 'tony', 'jerry']
    
    • 先取出数据值再删除:pop 默认取出列表尾部的数据值再删除
    l1 = ['jason', 'kevin', 'oscar', 'tony', 'jerry']
    res = l1.pop()
    print(l1, res) # ['jason', 'kevin', 'oscar', 'tony'] jerry
    
  • 查看数据值对于的索引值:index
l1 = ['jason', 'kevin', 'oscar', 'tony', 'jerry']
print(l1.index('jason'))
  • 统计某个数据值出现的次数:count
l1 = ['jason', 'kevin', 'oscar', 'tony', 'jerry']
l1.append('jason')
l1.append('jason')
l1.append('jason')
print(l1.count('jason'))
  • 排序
    • 升序:sort
    l2 = [77, 33, 22, 44, 55, 99, 88]
    l2.sort()
    print(l2)
    
    • 降序:sort(reverse=True)
    l2 = [77, 33, 22, 44, 55, 99, 88]
    l2.sort(reverse=True)
    print(l2)
    
  • 翻转:reverse 前后颠倒
l1 = ['jason', 'kevin', 'oscar', 'tony', 'jerry']
l1.reverse()
print(l1)
  • 比较运算
    • 按照位置一一比较
    • 不同数据类型之间无法直接作比较

元组内置方法

  • 类型转换:tuple()
  • 支持for循环的数据类型都可以转元组
  • 当元组内只有一个数据值,不能省略逗号,如果省略逗号括号里是什么类型就是什么类型
  • 遇到可以存储多个数据值的数据类型,如果里面只有一个数据值,逗号也要加上
t1 = () # tuple
print(type(t1))
t2 = (1,)  # tuple
print(type(t2))
t3 = (11.11,)  # tuple
print(type(t3))
t4 = ('jason',)  # tuple
print(type(t4))
  • 统计元组内数据值个数:len()
  • 查与改
print(t1[0])  # 可以查
t1[0] = 222  # 不可以改
  • 元组的索引不能改变绑定的地址
t1 = (11, 22, 33, [11, 22])
t1[-1].append(33)
print(t1)  # (11, 22, 33, [11, 22, 33])

字典内置方法

  • 字典很少涉及类型转换,都是直接定义
  • K是对V的描述性性质的信息,一般是字符串(K只要是不可变类型都可以),字典内k:v键值对是无序的
  • 取值:get()(推荐使用)
print(info['username'])  # 不推荐使用 键不存在会直接报错
print(info['xxx'])  # 不推荐使用 键不存在会直接报错
print(info.get('username'))  # jason
print(info.get('xxx'))  # None
print(info.get('username', '键不存在返回的值 默认返回None'))  # jason
print(info.get('xxx', '键不存在返回的值 默认返回None'))  # 键不存在返回的值 默认返回None
print(info.get('xxx', 123))  # 123
print(info.get('xxx'))  # None
  • 统计字典中键值对的个数:len()
  • 修改数据:键存在是修改
info['username'] = 'jasonNB'
print(info)
  • 新增数据:键不存在是新增
info['salary'] = 6
print(info)  # {'username': 'jason', 'pwd': 123, 'hobby': ['read', 'run'], 'salary': 6}
  • 删除数据

    • 方式一:通用删除:del 通过索引删除
    del info['username']
    print(info)
    
    • 方式二:pop()删除指定的key对应的键值对,并返回值
    res = info.pop('username')
    print(info, res)
    
    • 方式三:popitem()随机删除一组键值对,并将删除的键值放到元组内返回
    info.popitem()
    print(info)
    
  • 快速获取键、值、键值对数据

    • 获取字典所有的k值,结果当成是列表
      print(info.keys()) # dict_keys(['username', 'pwd', 'hobby'])
    • 获取字典所有的v值,结果当成是列表
      print(info.values()) # dict_values(['jason', 123, ['read', 'run']])
    • 获取字典kv键值对数据,组织成列表套元组
      print(info.items()) # dict_items([('username', 'jason'), ('pwd', 123), ('hobby', ['read', 'run'])])
  • 修改字典数据

info.update({'username':'jason123'})
print(info)
info.update({'xxx':'jason123'})
print(info)
  • 快速构造字典:给的值默认情况下所有的键都用一个
es = dict.fromkeys([1, 2, 3], None)
print(res)
new_dict = dict.fromkeys(['name', 'pwd', 'hobby'], [])  # {'name': [], 'pwd': [], 'hobby': []}
new_dict['name'] = []
new_dict['name'].append(123)
new_dict['pwd'].append(123)
new_dict['hobby'].append('read')
print(new_dict)

res = dict.fromkeys([1, 2, 3], 234234234234234234234)
print(id(res[1]))
print(id(res[2]))
print(id(res[3]))
  • 键存在获取键对应的值,键不存在则设置新值并返回设置的新值
res = info.setdefault('username', 'jasonNB')
print(res, info)
res1 = info.setdefault('xxx', 'jasonNB')
print(res1, info)

集合内置方法

  • 去重:集合去重有局限性

    • 只针对不可变类型
    • 集合本身是无序的,驱虫之后无法保留原来的顺序
    • 针对不可变类型去重且保留顺序
    l=[2, 3, 2, 1, 2, 3, 2, 3, 4, 3, 4, 3, 2, 3, 5, 6, 5]
    new_l=[]
    
    for dic in l:
    	if dic not in new_l:
        	new_l.append(dic)
    print(new_l) # [2, 3, 1, 4, 5, 6]
    
  • 集合的关系运算

    • 交集(&)
    • 差集(-)
    • 合集(|)
    • 对称差集(^)
    • 父集子集
f1 = {'jason', 'tony', 'oscar', 'jerry'}
f2 = {'kevin', 'jerry', 'jason', 'lili'}

# 求f1和f2的共同好友
print(f1 & f2)  # {'jason', 'jerry'}
# 求f1/f2独有好友
print(f1 - f2)  # {'oscar', 'tony'}
print(f2 - f1)  # {'lili', 'kevin'}
# 求f1和f2所有的好友
print(f1 | f2)  # {'jason', 'kevin', 'lili', 'oscar', 'jerry', 'tony'}
# 求f1和f2各自独有的好友(排除共同好友)
print(f1 ^ f2)  # {'kevin', 'lili', 'tony', 'oscar'}

可变类型与不可变类型

  • 可变类型:值发生改变,内存地址不变,id不变,证明在改变原值
    • 列表类型:值改变内存地址不变
  • 不可变类型:值发生改变,内存地址也发生改变,id也变,证明是没有改变原值,产生了新的值
    • 数字类型(整型/浮点型):内存地址改变
    • 字符串类型:内存地址改变
    • 元组类型:元组内的元素无法修改,指的是元组内索引指向的内存地址不能被修改,如果元组中存在可变类型,是可以修改,但是修改后的内存地址不变
    • 字典类型:值改变的情况下,字典的id不变

练习

# 1.利用列表编写一个员工姓名管理系统
# 	输入1执行添加用户名功能
# 	输入2执行查看所有用户名功能
#  	输入3执行删除指定用户名功能
# 	ps:思考如何让程序循环起来并且可以根据不同指令执行不同操作
# 	提示: 循环结构 + 分支结构
# 	拔高: 是否可以换成字典或者数据的嵌套使用完成更加完善的员工管理而不是简简单单的一个用户名

name_list = []
# 3.添加循环
while True:
    # 4.添加功能提示
    print("""
        1.添加用户名功能
        2.查看所有用户名功能
        3.执行删除指定用户名功能
    """)
    # 1.获取用户输入的指令
    choice = input('please input your command>>>:').strip()
    # 2.判断用户输入的指令 利用print模拟功能
    if choice == '1':
        # 6.获取用户输入的用户名
        username = input('please input your username>>>:').strip()
        # 7.判断当前用户名是否已存在
        if username in name_list:
            print('用户名已存在')
        else:
            name_list.append(username)
            print(f'用户:{username}添加成功')
    elif choice == '2':
        # 8.查看所有用户 本质就是打印列表  但是我们可以稍微美化一下
        for name in name_list:
            print(f"""
            ---------------info--------------
            username:{name}
            ---------------------------------
            """)
    elif choice == '3':
        # 9.获取想要删除的用户名
        target_name = input('please input target_name to delete>>>:').strip()
        if target_name not in name_list:
            print('你是不是傻 没有这个人 删你妹啊!!!')
            continue
        # 10.直接删除
        name_list.remove(target_name)
        print(f'用户名{target_name}删除成功')
    else:
        print('指令错误,请重新输入')


# 2.统计列表中每个数据值出现的次数并组织成字典战士
# 	eg: l1 = ['jason','jason','kevin','oscar']
#       结果:{'jason':2,'kevin':1,'oscar':1}
# 	真实数据
#     	l1 = ['jason','jason','kevin','oscar','kevin','tony','kevin']

l1 = ['jason', 'jason', 'kevin', 'oscar', 'kevin', 'tony', 'kevin']
# 定义一个空字典
data_dict = {}
# 循环获取到列表中每一个数据值
for name in l1:
    # 判断当前数据值是否已经存在于字典的k中
    # 如果不存在 则新增一个键值对(第一次出现)
    if name not in data_dict:
        data_dict[name] = 1
    # 如果存在 则让该键对应的值自增1(重复出现)
    else:
        data_dict[name] += 1  # 获取键对应的值并自增1  data_dict[name] = data_dict[name] + 1
print(data_dict)



# 3.编写员工管理系统
#     1.添加员工信息
#     2.修改员工薪资
#     3.查看指定员工
#     4.查看所有员工
#     5.删除员工数据
#     提示:用户数据有编号、姓名、年龄、岗位、薪资
#     数据格式采用字典:思考如何精准定位具体数据>>>:用户编号的作用

# 定义存储用户数据的字典
data_dict = {}  # {'1':{}, '2':{}, '3':{} }

while True:
    print("""
        1.添加员工信息
        2.修改员工薪资
        3.查看指定员工
        4.查看所有员工
        5.删除员工数据
    """)
    # 获取用户输入的功能编号
    func_id = input('请输入功能的编号>>>:').strip()
    # 判断用户输入的功能编号
    if func_id == '1':
        # 获取用户数据
        emp_id = input('请输入员工编号>>>:').strip()
        # 针对员工编号应该做不重复校验
        if emp_id in data_dict:
            print('该员工编号已经存在')
            continue
        emp_name = input('请输入员工姓名>>>:').strip()
        emp_age = input('请输入员工年龄>>>:').strip()
        emp_job = input('请输入员工岗位>>>:').strip()
        emp_salary = input('请输入员工薪资>>>:').strip()
        # 构造存储用户数据的小字典
        temp_dict = {}
        # 将员工数据全部录入该小字典
        temp_dict['emp_id'] = emp_id
        temp_dict['emp_name'] = emp_name
        temp_dict['emp_age'] = emp_age
        temp_dict['emp_job'] = emp_job
        temp_dict['emp_salary'] = emp_salary
        # 将员工数据小字典当做大字典的值添加
        data_dict[emp_id] = temp_dict  # {'1':{}}
    elif func_id == '2':
        # 获取员工编号
        target_emp_id = input('请输入想要修改的员工编号>>>:').strip()
        # 判断当前员工编号是否存在
        if target_emp_id not in data_dict:
            print('当前员工编号不存在 无法修改!!!')
            continue
        # 根据员工编号获取该员工的详细数据(小字典)
        emp_data = data_dict.get(target_emp_id)  # {}
        # 获取新的员工薪资
        new_salary = input('请输入该员工新的薪资>>>:').strip()
        # 修改员工小字典中薪资对应的值
        emp_data['emp_salary'] = new_salary
        # 将修改之后的小字典重新赋值到大字典中
        data_dict[target_emp_id] = emp_data
        # 人性化提示(也可以不写)
        print(f'员工编号:{target_emp_id} 员工姓名:{emp_data.get("emp_name")}薪资修改成功')
    elif func_id == '3':
        # 获取员工编号
        target_emp_id = input('请输入想要查询的员工编号>>>:').strip()
        # 判断当前编号是否存在
        if target_emp_id not in data_dict:
            print('当前员工编号不存在')
            continue
        # 根据员工编号获取员工数据字典
        emp_data = data_dict.get(target_emp_id)
        # 格式化输出员工数据
        print(f"""
        --------------------emp of info------------------
        编号:{emp_data.get('emp_id')}
        姓名:{emp_data.get('emp_name')}
        年龄:{emp_data.get('emp_age')}
        岗位:{emp_data.get('emp_job')}
        薪资:{emp_data.get('emp_salary')}
        -------------------------------------------------
        """)
    elif func_id == '4':
        # 获取所有员工数据小字典
        all_emp_data = data_dict.values()  # [{},{},{}]
        # 循环获取每一个员工数据字典
        for emp_data in all_emp_data:  # {}
            # 格式化输出员工数据
            print(f"""
                    --------------------emp of info------------------
                    编号:{emp_data.get('emp_id')}
                    姓名:{emp_data.get('emp_name')}
                    年龄:{emp_data.get('emp_age')}
                    岗位:{emp_data.get('emp_job')}
                    薪资:{emp_data.get('emp_salary')}
                    -------------------------------------------------
                    """)
    elif func_id == '5':
        # 获取想要删除的员工编号
        target_delete_id = input("请输入想要删除的员工编号>>>:").strip()
        # 判断员工编号是否存在
        if target_delete_id not in data_dict:
            print('员工编号不存在')
            continue
        # 根据员工编号删除键值对
        data_dict.pop(target_delete_id)
        print(f'员工编号{target_delete_id}数据删除成功')
    else:
        print('输入指令错误,请重新输入')


垃圾回收机制

  • 垃圾回收机制:是Python解释器自带一种机制,专门用来回收不可用的变量值所占用的内存空间(引用计数机制为主,标记-清除和分代收集两种机制为辅)

  • 引用计数:变量值被变量名关联的次数

    • 缺点:循环引用
    • 解决办法:标记清除、分代回收、手动GC
  • 标记清除:专门解决循环引用的问题

    • 标记:将内存中程序产生的所有数据值全部检查一遍,然后将所有可以直接或间接访问到的对象标记为存活的对象,其余的均为非存活对象
    • 清除:清除过程中遍历堆中所有的对象,将没有标记的对象全部清除
  • 分代回收:是一种以空间换时间的操作方式,Python将内存根据对象的存活时间划分为不同的集合,每个集合称为一个代

    • 年轻代(第0代):新创建的对象分配在年轻代,年轻代链表的总数达到上限时,Python垃圾收集机制就会被触发,把不会回收的对象移到中年代
    • 中年代(第1代):不会回收的对象移到中年代
    • 老年代(第2代):老年代中的对象是存活时间最久的对象,存活于整个系统的生命周期内

字符编码

  • 发展史:
    • 阶段一:一家独大(ASCII码)
    • 阶段二:群雄割据(GBK码、Euc_kr码、shift_JIS码)
    • 阶段三:天下统一(万国码Unicode)
  • 编码解码
    • 编码(encode):将人类能够读懂的字符翻译成计算机能够读懂的字符
    • 解码(decode):将计算机能够读懂的字符翻译成人类能够读懂的字符
  • 乱码:当一组数据用不同的字符编码进行编码解码时,就会出现乱码的情况
    • 解决乱码措施:什么编码存就用什么编码解
  • Python默认编码
    • python2.x默认的字符编码是ASCII(不支持中文),默认的文件编码是ASCII
      • python解释器可以识别中文和其他语言的方法
        • 方法一:告知python解释器,这个.py文件里的文本是用UTF-8编码的(coding:utf8 或 -- coding:utf8 --,声明的编码方式要与.py文件的编码方式一致)
        • 方法二:在定义字符串时习惯在前面加u
    • python3.x默认的字符编码是Unicode(支持中文),默认的文件编码是UTF-8
      • python3严格区分了bytes和str,二者不能进行拼接。文本总是unicode,有str表示;二进制数据则由bytes表示

文件处理

基本流程

  • 流程
    • 1.打开文件(open())
    • 2.操作文件(read()/write())
    • 3.关闭文件(close())
  • open函数:open(文件路径, 读写模式, 字符编码)
  • read方法(f.read()):从一个打开的文件中读取一个字符串
    • 注意:Python字符串可以是二进制数据,而不是仅仅是文字
  • write方法(f.write()):可以将任何字符串写入一个打开的文件
    • 注意:
      • Python字符串可以是二进制数据,而不是仅仅是文字
      • write()方法不会在字符串的结尾添加换行符('\n')
  • close方法(f.close()):刷新缓冲区里任何还没写入的信息,并关闭该文件,这之后便不能再进行写入
    • 注意:当一个文件对象的引用被重新指定给另一个文件时,Python会关闭之前的文件,用 close()方法关闭文件
  • 资源回收
    • f.close():回收操作系统打开的文件资源
    • del f:回收应用程序级的变量
      • del f一定要发生在f.close()之后
      • 操作完毕文件后,一定要f.close()
  • with方法:
    • 语法结构:with open('a.txt', 'w', encoding='utf8') as f:
    • 执行完子代码块后,with 会自动执行f.close()
    • with同时打开多个文件,逗号分隔开即可

文件操作模式

  • r模式(read):只读模式,只读不写
    • 文件路径不存在,r模式直接报错
    • 文件路径存在,r模式会打开文件等待读取文件内容
  • w模式(write):只写模式,只写不读
    • 在文件不关闭的情况下连续写入,后写内容一定跟在前写的内容后面
    • 重新用w模式打开文件会清空文件内容
    • 文件路径不存在, w模式会自动创建该文件
    • 文件路径存在,w模式会先清空文件内容,之后等待填写新内容
  • a模式(append):只追加模式,在文件末尾添加内容
    • 文件路径不存在: a模式会自动创建该文件
    • 文件路径存在: a模式不会先清空该文件内容,只在在文件末尾等待填写新内容
  • +模式(r+/w+/a+):可读可写
    • 在平时工作中,我们只单纯使用r/w/a,要么只读,要么只写,一般不用可读可写的模式
  • w模式与a模式异同
    • 相同点:在打开的文件不关闭的情况下,连续的写入,新写的内容总会跟在前写的内容之后
    • 不同点:以a模式重新打开文件,不会清空原文件内容,会将文件指针直接移动到文件末尾,新写的内容永远写在最后
  • t模式(rt/wt/at):文本模式(默认)
    • 注意:
      • 只能操作文本文件
      • 必须指定encoding参数
      • 读写以字符串为单位
  • b模式(rb/wb/ab 不能省略b):二进制模式(可以操作任意类型的文件)
    • 注意:
      • 能够操作所有类型的文件
      • 不需要指定encoding参数
      • 读写以bytes为单位
  • b模式对比t模式
    • 纯文本文件:t模式省去编码和解码的环节,b模式需要手动编码和解码,t模式更方便
    • 非文本文件(图片、视频、音频):只能使用b模式
    • t/b模式必须与r/w/a之一结合使用

控制文件内指针移动

  • 文本模式:read()括号内的数字表示读取几个字符
  • 二进制模式:read()括号内的数字表示读取及格字节(英文1字节,中文3字节)
  • tell方法(tell()):获取光标移动字节数
  • seek方法:主动控制文件内指针的移动
    • 语法结构:seek(offset,whence)
      • offset:指针移动的字节数
      • whence:模式控制
        • 0模式(默认模式):基于文件开头移动的多少字节
        • 1模式:基于光标当前所在位置移动多少字节(只能在二进制模式使用)
        • 2模式:基于文件末尾移动多少字节(只能在二进制模式使用)

文件其他操作模式

  • readline()方法:一次只读取一行内容,光标移动到第二行首部
  • readlines()方法:读取每一行内容,存放于列表中
  • readable()方法:判断当前文件是否可读
  • writeable()方法:判断当前是否可写
  • writelines()方法:支持填写内容容器类型(内部可以存放多个数据值的数据类型)多个数据值
  • flush方法:将内存中的文件数据立刻刷到硬盘(相当于主动按Ctrl+s)

文件数据修改

  • 覆盖写:读取文件的内容一次性全部读入到内存,在内存中完成修改再覆盖写回原文件

    • 优点:硬盘只占用一块空间
    • 缺点:数据量较大的时候会内存溢出
  • 重命名:先读取文件内容到内存,在内存中完成修改,之后保存到另一个文件中再将原文件删除,将新的文件重命名为原文件

    • rename()方法两个参数,当前文件名和新文件名
      • 优点:不会占用过多的内存
      • 缺点:文件修改过程中同一份数据存了两份
  • 删除文件

    • remove()方法:需要提供要删除的文件名作为参数

练习

# 利用文件充当数据库编写用户登录、注册功能
# 	文件名称:userinfo.txt
# 	基础要求:
# 		用户注册功能>>>:文件内添加用户数据(用户名、密码等)
#        用户登录功能>>>:读取文件内用户数据做校验
#       ps:上述功能只需要实现一次就算过关(单用户) 文件内始终就一个用户信息
#  	拔高要求:
#        用户可以连续注册
#    		用户可以多账号切换登录(多用户)  文件内有多个用户信息
#       ps:思考多用户数据情况下如何组织文件内数据结构较为简单
#    	提示:本质其实就是昨天作业的第二道题 只不过数据库由数据类型变成文件

while True:
    print("""
    1.用户注册
    2.用户登录
    3.退出
    """)
    choice = input('请输入您想要操作的指令:')
    if choice == '1':
        user_name = input('请输入用户名:').strip()
        with open(r'userinfo.txt', 'r', encoding='utf8') as f:
            for line in f:
                real_name = line.split('|')[0]
                if real_name == user_name:
                    print('用户名已存在,请重新输入')
                    break
            else:
                user_pwd = input('请输入密码:').strip()
                user_data = '%s|%s\n' % (user_name, user_pwd)
                with open(r'userinfo.txt', 'a', encoding='utf8') as f:
                    f.write(user_data)
                print(f'用户{user_name}注册成功')
    elif choice == '2':
        user_name = input('请输入用户名:').strip()
        user_pwd = input('请输入密码:').strip()
        with open(r'userinfo.txt', 'r', encoding='utf8') as f:
            for line in f:
                real_name, real_pwd = line.split('|')
                if user_name == real_name and user_pwd == real_pwd.rstrip('\n'):
                    print('用户登录成功')
                    break
            else:
                print('用户名或密码错误,用户登录失败')
    elif choice == '3':
        print('退出成功')
        break
    else:
        print('输入指令错误,请重新输入')

函数

函数定义调用

  • 函数定义
    • 语法结构
    def 函数名(参数1,参数2):
    	'''函数注释'''
    	函数体代码
    	return 返回值
    # def:定义函数的关键字
    # 函数名:与变量名的命名一致
    # 括号 :定义函数函数名后面必须跟括号,任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数
    # 参数:可写可不写,用于接收外界传递给函数体代码内部的数据
    # 冒号:括号后要加冒号,然后在下一行开始缩进编写函数体的代
    # 函数注释:类似于说明书 用于介绍函数的主题功能和具体用法
    # 函数体代码:整个函数最核心的区域(逻辑代码)
    # return:结束函数,选择性地返回一个值给调用方
    
  • 函数调用:
    • 语句形式
    • 表达式形式
    • 函数调用作为参数形式
  • 注意:
    • 1.函数必须先定义后使用
    • 2.定义函数使用def关键字,调用函数使用函数名加括号
    • 3.函数在定义阶段只检测函数体代码语法,不执行函数体代码
    • 4.运行代码就需要调用函数
    • 5.函数名加括号执行优先级最高

函数分类

  • 内置函数:解释器提前定义好的函数,用户可以直接调用

    • 注意:内置函数可以直接调用,但是数据类型的内置方法(函数)必须使用数据类型点的方式才能调用,相当于是数据类型独有的一些内置方法
  • 自定义函数

    • 空函数:函数体代码pass顶替
    • 无参函数:函数定义阶段括号内没有填写参数
      • 注意:函数名加括号即可调用
    • 有参函数:函数定义阶段括号内有填写参数
      • 注意:调用需要函数名加括号并给数据值

函数返回值

  • 返回值:调用函数之后产生的结果,可有可无
  • return关键字
    • 1.没有return关键字:默认返回None
    • 2.有return关键字:后面不写,也返回None
    • 3.有return关键字:return后面写什么就返回什么(如果是数据值则直接返回 如果是变量则需要找到对应的数据值返回)
    • 4.有return关键字并且后面写了多个数据值(名字) 逗号隔开:默认情况下回自动组织成元组返回
    • 5.遇到return关键字会立刻结束函数体代码的运行

参数

  • 形式参数:简称“形参”,函数在定义阶段括号内填写的参数,形参本质就是一个变量名,用来接收外部传来的值
  • 实际参数:简称“实参”,函数在调用阶段括号内填写的参数,值可以是常量、变量、表达式或三者的组合
  • 位置参数
    • 位置形参:在函数定义阶段括号内从左往右依次填写的变量名称
    • 位置实参:在函数定义阶段括号内从左往右依次填写的数据值
    • 注意:
      • 实参可以是数据值也可以是绑定了数据值的变量名
      • 给位置形参传值时必须个数一致
  • 关键字参数
    • 关键字实参:在函数调用阶段括号内以什么等于什么的形式传值
    • 注意:
      • 指名道姓的给形参传值
      • 位置实参必须在关键字实参前面(遵循短的(简单)的在前面,长的(复杂的)在后面)
      • 同一个形参在一次调用中只能传一次值
  • 默认值参数
    • 注意:
      • 默认参数必须在位置参数之后
      • 在函数定义阶段就给形参绑定值,后续调用阶段就可以不传
      • 调用阶段不传值就使用默认的,传了就用传了的
      • 遵循短的(简单)的在前面,长的(复杂的)在后面
  • 可边长参数
    • 可变长形参:可以打破形参与实参的个数限制,随意传值
    • ‘* 在形参中的作用,接收多余的位置参数并组织成元组的形式赋值给 * 后面的变量名
    • ** 在形参中的作用,接收多余的关键字参数并组织成字典的形式赋值给** 后面的变量名
 posted on 2022-07-03 20:06  念白SAMA  阅读(60)  评论(0)    收藏  举报