python 入门

124 阅读15分钟

本文是根据B站视频整理

python 基础

  • python 是动态语言,一切皆对象,所有对象都有一个布尔值, 内置函数bool()获取
  • 不可变序列:字符串、元组 (没有增删改)
  • 可变序列:列表、字典(有增删改,对象地址不发生改变)

image.png

数据结构是否可变是否重复是否有序定义符号
列表(list)有序[]
元组(tuple)有序()
字典(dict)key:否,value:是无序{key: value}
集合(set)无序{}

环境:

  • 开发工具:pycharm(官方下载)
  • python 解释器(官方下载)

将输出结果输出到文件

    fp = open('D:/text.txt', 'a+')  
    print('hello world', file=fp)  
    fp.close()

变量

由三部分组成

  • 标识: 对象所存储的内存地址,内置函数id(obj)获取
  • 类型:对象的数据类型,内置函数type(obj)获取
  • 值:对象存储的具体数据

image.png

数据类型

常用: int、float、bool、str

  • int: 整数 负数 0
  • float:整数和小数组成, 计算时需导入decimal 模块,进行精确计算
  • bool:True, False
  • str: 单引号,双引号,三引号

image.png

image.png

数值类型转换

内置函数 int()、float()、bool()、str()

进制

进制开头例子解析方法反解析
二进制0b0b010101chr(进制)odr(进制)
八进制0o0o172546chr(进制)odr(进制)
十进制182chr(进制)odr(进制)
十六进制0x0x9aef45127chr(进制)odr(进制)

查看保留字符

    import keyword
    print(keyword.kwlist)

注释

# coding:utf-8
# coding:gbk
...

image.png

运算符

print(1+1) # 加
print(10-1) # 减
print(1*2) # 乘除
print(11/2) # 除
print(11//2) # 整除
print(11%2) # 取余
print(11**5) # 11 的 5 次方

print(11//2) # 整除  5
print(-11//-2) # 整除  5
# 一正一负 向下取整
print(-11//2) # 整除 -5
print(11//-2) # 整除 -5

print(11%2) # 取余 1 公式:余数=被除数-除数*商
print(9%-4) # -3 套公式: 9-(-4)*(-3) => 9-12 => -3
print(-9%4) # 3 套公式: -9-4*(-3) => -9-(-12) => 3

# 交换解包赋值运算
a,b = 10,20
a,b = b,a

# 比较
a,b = 10,10
print(a == b) # False 比较的是值
print(a is b) # True 比较的是标识, 内置函数id(obj)获取
# bool 运算符
a,b = 1,2
print(a == 1 and b == 2) # True
print(a == 1 and b < 2) # False
print(a == 1 or b < 2) # True
f = True
print(not f) # False 取反
# 是否存在
s='holleword'
print('w' in s) # True
print('k' in s) # False
# 位运算
print(4&8) # 按位&,同为1时结果为1 (下面的图一)
print(4|8) # 按位|,同为0时结果为0 (下面的图一)
print(4<<1) # 向左移动1位,相当于乘2(下面的图二1)
print(4<<2) # 向左移动2位,相当于乘4(下面的图二1)
print(4>>1) # 向右移动1位,相当于除以2 (下面的图二2)
print(4>>2) # 向右移动2位,相当于除以4 (下面的图二2)

image.png

图一

image.png

图二

  • (1) image.png

  • (2) image.png

运算优先级

算术运算 》 位运算 》 比较运算 》 布尔运算 》 赋值运算

image.png

函数

创建

  • 返回值是多个时返回一个元组,一个就是本身
  • def fun(*args) 可变的位置参数 结果: 元组
  • def fun(**args) 可变的关键字参数 结果: 字典
  • *args,**args 作为形参时只能存在一个
def funcName(a,b):
    return a+b
    
def funcName1(a,b,*,c,d):
    print('设置成了后面两个必须为关键字参数')
    
funcName1(1,2,c=2,d=4)

input 函数

present = int(input('请输入一个字符串数'))
print('你输入了:', present)

image.png

range 函数

用于生成一个整数序列

start = 1
stop = 10
step = 1
range(stop) # 创建一个[0, stop) 之间的整数列,步长为1
range(start, stop) # 创建一个[start, stop) 之间的整数列,步长为1
range(start, stop, step) # 创建一个[start, stop) 之间的整数列,步长为step
# 查看
print(list(range(2))) # [0,1]

条件表达式

pass 语句 用来占位不做任何操作

a = 1
if a == 1:
    print('没生病')
elseif a == 2
    pass
else:
    print('生病了')
# 简写
print('没生病' if a == 1 else '生病了')

循环表达式

  • break 中断循环
  • continue 结束本次循环,进入下一次循环
# while 判断n+1次 执行 n次
a = 1
while a < 10:
    print(a)
    a+=1
# for-in
for item in 'Python'
    print(item)
    if item == 't'break

列表的方法

创建: list() 或 []

mylist = [0,1,2,3]

  • 获取索引:index()
  • 切片操作:属于拷贝,不改变源列表。例子:mylist[开始切片的下标:结束切片的下标:可选步长]
  • 判断是否在列表 mylist in 'xxx'
  • 末尾追加:mylist.append()
  • 数组合并:mylist.extend()
  • 任意插入元素:insert(索引,值)
  • mylist[1::] = [10] # [0,1,10]
  • mylist[1:3] = [4,5,6] # [0,4,5,6,3]
  • 移除第一个符合的元素:mylist.remove(指定元素)
  • 根据索引移除,不指定移除最后一个:mylist.pop(索引)
  • 清空:mylist.clear()
  • 删除列表del mylist
  • 排序(改变源列表):升序->mylist.sort() 降序->mylist.sort(reverse=True)
  • 排序(不改变源列表): 内置函数 sorted(mylist) 同上, 例子:sorted(mylist, reverse=True)
[ i*i for i in range(1, 10) ]

image.png

字典

  • 创建: dict(name=xx,age=xx) 或 {}

mydict = {'name': '张三'}

  • 获取:mydict.get(name)
  • 获取:mydict[name]
  • 删除指定的键值对:del mydict[name]
  • 清空:mydict.clear()
  • 新增:mydict['age'] = 231
  • 获取全部键:mydict.keys()
  • 获取全部值:mydict.values()
  • 获取全部键值对(元组列表):mydict.items()
items = ['1','2']
prices = [96,1]
{ item:price for item,price in zip(items,prices) }

image.png

元组(不可变序列)

  • 创建:() 或 tuple()

t2 =('1',) 或 t2 ='1','11'

  • 获取:t2[0]

集合(成员是唯一的做了去重)

创建: {'123','2'} 或 set() myset = {'123','2'}

  • 添加:myset.add(元素)
  • 合并集合(元组、列表、字符串列表、集合):myset.update()
  • 删除指定元素:myset.remove(元素)
  • 删除指定元素:myset.discard(元素)
  • 删除随机一个元素(无参):myset.pop()
  • 清空:myset.clear()
s1 = {1,2}
s2 = {2,1}
print(s1 == s2) # 判断内容相等 结果 True
s3 = {1}
print(s1.issuperset(s3)) # s1 是 s3 的超集 结果 True
print(s3.issubset(s1)) # s3 是否是s1 的子集 结果 True
print(s2.isdisjoint(s1)) # s2 s1 是否交集 结果 True

print(s2.intersection(s1))  # 交集
print(s2 & s1) # 交集

print(s2.union(s1))  # 并集
print(s2 | s1)  # 并集

print(s1.difference(s3)) # s1的 差集
print(s1 - s3) # s1的 差集

print(s1.symmetric_difference(s3)) # s1的 对称差集
print(s1 ^ s3) # s1的 对称差集
{ i*i for i in range(1,10) }

image.png

image.png

字符串

  • 驻留机制(编辑其PyCharm 对这个做了优化) image.png

image.png

mystr = ''
mystr1 = 'abc%' # 不产生驻留
mystr2 = 'abc%' # 不产生驻留
mystr.join(['ab', 'c']) # 不产生驻留
mystr1.intern(mystr2) # 使其 强制驻留

mystr = 'holleword'

  • 查找符合的第一个下标,没找到报错: mystr.index(元素)
  • 查找符合的最后一个下标,没找到报错:mystr.rindex(元素)
  • 查找符合的第一个下标,没找到返-1:mystr.find(元素)
  • 查找符合的最后一个下标,没找到返-1:mystr.rfind(元素)
  • 分割: mystr.slit()
  • 分割: mystr.rslit()
  • 替换:mystr.replace()
  • 合并:mystr.join()
  • 切片: mystr[0:5:1]
  • 大写:mystr.upper()
  • 小写:mystr.lower()
  • 反大小写:mystr.swapcase()
  • 第一个大写其他小写:mystr.capitalize()
  • 每个单词第一个大写:mystr.title()
  • 居中:mystr.center(宽度, 填充符)
  • 左:mystr.ljust(宽度, 填充符)
  • 右:mystr.rjust(宽度, 填充符)
  • 居中:mystr.zfill(宽度)
  • 是否标识符组成:mystr.isidentifier()
  • 是否空白字符组成:mystr.isspace()
  • 是否字母组成:mystr.isalpha()
  • 是否十进制的数字组成:mystr.isdecimal()
  • 是否数字组成:mystr.isnumeric()
  • 是否字母和数字组成:mystr.isalnum()

占位符

  • %
name = '张三'
age = 26
print('我叫{0},今年{1}'.format(name, age))
print('%10d' % 99) # d 表示数值, 10 表示宽度 数值.
print('%.3f' % 3.1415926) # f 表示浮点数, .3 表示保留小数位.

  • {}
name = '张三'
age = 26
print('我叫{0},今年{1}'.format(name, age))
print('{}'.format(3.1415926)) # 3.1415926
print('{0:.3}'.format(3.1415926)) # 一共三位数 . 结果: 3.14
print('{0:.3f}'.format(3.1415926)) # 保留三位数小数 . 结果: 3.141
print('{:10.3f}'.format(3.1415926)) # 宽度为10 保留三位数小数. 结果: 3.141
  • {变量}
name = '张三'
age = 26
print(f'我叫{name},今年{age}')

编码转换

  • 编码:字符串转为二进制(bytes)
  • 解码: 二进制(bytes)转为字符串
name = '张三'
name1 = name.encode(encoding='GBK')
name2 = name.encode(encoding='UTF-8')
# 编码
print(name.encode(encoding='GBK'))
print(name.encode(encoding='UTF-8'))
# 解码
print(name1.decode(encoding='GBK'))
print(name2.decode(encoding='UTF-8'))

异常处理

try except

try:
    # 填写代码
except ValueError:
    #ValueError 异常处理代码
except BaseException as e: # 未知错误
    # BaseException 异常处理代码
    print('出错了', e)
except ....

try except else

try:
    # 填写代码
except BaseException as e: # 未知错误
    # 失败
    print('出错了', e)
else:
    #成功

try except else finally

try:
    # 填写代码
except BaseException as e: # 未知错误
    # 失败
    print('出错了', e)
else:
    #成功
finally:
    #无论是否产生异常都会被执行

常见异常

序列号异常类型描述
2ZeroDivisionError除(获取模)零(所有数据类型)
3indexError序列中没有此索引(index)
4keyError映射中没有这个键(key)
5NameError为声明/初始化对象(没有该属性)
6SyntaxErrorPython 语法错误
7ValueError传入无效参数

Python的异常处理机制

traceback 模块

  • 用来打印异常信息 生产日志文件
import traceback
try:
except:
    traceback.print_exc()

編程思想

image.png

由类属性、实例方法、静态方法、类方法组成

class Student:
    #属性
    native_pace='吉林'
    # 初始化方法
    def __init__(self,name,age):
        # self代表自身,self.name 实例属性,将局部变量的name赋值给了实体属性
        self.name = name
        self.age = age
        print('初始化方法')
    #实例方法
    def eat(self):
        print('学生在吃饭')
    #静态方法
    @staticmethod
    def method(): #不允许self
        print('使用了@staticmethod进行修饰,就是静态方法')
    #类方法
    @classmethod
    def mc(cls): #必须填写 cls
        print('使用了@classmethod进行修饰,就是类方法')
        
# 创建实例
stul = Student('张三',13)
stu2 = Student('李四',14)
Student.native_pace = '天津' # stul/stu2 的类指针指向类 所以实例中的native_pace都被改变了
print(stul.native_pace) # 天津
print(stu2.native_pace) # 天津
stu2.gender = '女'
Student.eat(stu1) # 相当于 stu1.eat()

封装

提高安全性

class Student:
    def __init__(self,name,age):
        self.name = name
        self.__age = age
    def info(self):
        print(self.name, self.__age)
sut = Student('张三', 20)
print(sut.name)
print(sut.__age) # 访问不了 通过print(sut.__Student__age)可以访问

继承

提高复用性

  • 继承和方法重写
class Person(object): # Person 继承object类 可省略
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def info(self):
        print(self.name, self.age)

class Student: # Student 继承Person类
    def __init__(self,name,age,stu_no):
        super().__init__(name,age)
        self.stu_no = stu_no
    def info(self): # 重写了父类Person的info方法
        super().info() # 调用父类Person的info方法
        print(self.name, self.age,self.stu_no)
        
class Teacher: # Teacher 继承Person类
    def __init__(self,name,age,teachofyear):
        super().__init__(name,age)
        self.teachofyear = teachofyear
    def info(self): # 重写了父类Person的info方法
        super().info() # 调用父类Person的info方法
        print(self.name, self.age,self.teachofyear)
       
sut = Student('张三', 18, '20200211')
tea = Teacher('李四', 20, 10)
sut.info()
tea.info()
  • 多继承
class A(object):
    pass
class B(object):
    pass
class A(A,B):
    pass

多态

提高扩展性和可维护性

image.png

特殊属性

特殊属性异常类型描述
特殊属性__dict__获得类对象或实例对象所绑定的所有属性和方法的字典
特殊方法__init__()对创建对象进行初始化
特殊方法__len__()通过重写__len__()方法,让内置函数len()的参数可以是自定义类型
特殊方法__add__()通过重写__add__()方法,可使用自定义对象具有“+”功能
特殊方法__new__()用于创建对象
class A(object):
    pass
class B(object):
    pass
class A(A,B):
    pass
x=C('jack', 20)
print(x.__dict__) # 实例对象所绑定的所有属性和方法的字典
print(C.__dict__) # 类对象所绑定的所有属性和方法的字典

class Student:
    def __init__(self,name):
        self.name = name
    def __add__(self,other):
        return self.name + other.name
    def __len__(self):
        return len(self.name) # len 是内置函数
     
stu1 = Student('张三')
stu2 = Student('李四')
s = stu1 + stu2 # 相同结果 s= stu1.__add__(stu2)
print(s)
print(len(stu1))

image.png

模块

demo1

def add(a,b):
    return a+b
if __name__ == '__main__': # 只有在当前模块中才能运行 __name__是记录当前执行模块的变量
    print(add(10,20))

demo2

from demo1
demo1.add(100,200)

  • 包含__init__.py文件的目录称为包
  • 目录里通常不包含__init__.py文件

image.png

from pageage1 import module_A
from pageage1.module_A import a

常用内置模块

w3cschool 中有部分 python Api文档

模块名描述
sys与python解释器及其环境操作相关的标准库
time提供与时间相关的各种函数的标准库
os提供了访问操作系统服务功能的标准库
calendar提供了与日期相关的各种函数的标准库
urllib用于读取来自网上(服务器)的数据标准库
json用于使用JSON序列化和反序列化对象
re用于在字符串中执行正则表达式匹配和替换
math提供标准算术运算函数的标准库
decimal用于进行精确控制运算精度、有效数位和四舍五入操作的十进制运算
logging提供了灵活的记录事件、错误、警告、和调试信息等日志信息的功能
  • os
方法名描述
os.getcwd()放回当前工作目录
os.listdir(path)返回指定路径下的文件和目录信息
os.mkdir(path[,mode])创建目录
os.makedirs(path1/path2...[,mode])创建多级目录
os.rmdir(path)删除目录
os.removedirs(path1/path2...)删除多级目录
os.chdir(path)将path设置为当前工作目录

第三方模块的安装

pip install xxx
模块名描述
schedule定时任务

编码格式

image.png

io操作(input\output)

file = open('b.text', 'r') # r w a b +
file.readlines()
file.write('python')
file.close()

文件对象的一些常用方法

方法名描述
read([size])从文件中读取size个字节或字符内容的放回,若省略[size],则读取到文件末尾,即一次读取文件所有内容
readline()从文本文件中读取第一行内容
readlines()把文本文件中每一行都作为独立的字符串对象,并将这些对象放入列表返回
write(str)将字符串str内容写入文件
writelines(s_list)将字符串列表s_list写入文本文件,不添加换行符
seek(offset[,whence])把文件移动到新的位置,offset表示相对于whence的位置:
offset:为正往结束方向移动,为负往开始方向移动
whence:不同的值代表不同含义:
0:从文件开头计算(默认值)
1:从文件当前位置计算
2:从文件尾开始计算
tell()返回文件指针的当前位置
flush()把缓冲区的内容写入文件,但不关闭文件
close()把缓冲区的内容写入文件,同时关闭文件,释放文件对象相关资源

with 语句(上下文管理器)

自动管理上下文资源,不论什么原因跳出with都能确保文件正确的关闭,以此来达到释放资源的目的

image.png

学生管理系统实例

import os  
  
filename = 'student.txt'  
sortArr = ['english', 'python', 'java']  
boolArr = [True, False]  
  
def main():  
    while True:  
        menm()  
        choice = int(input('请选择'))  
        if choice in range(0, 8):  
            if choice == 0:  
                answer = input('您确定要退出系统吗?Y/N')  
                if answer == 'y' or answer == 'Y':  
                    print('谢谢使用')  
                    break  
                else:  
                    continue  
            elif choice == 1:  
                insert()  
            elif choice == 2:  
                search()  
            elif choice == 3:  
                delete()  
            elif choice == 4:  
                modify()  
            elif choice == 5:  
                sort()  
            elif choice == 6:  
                total()  
            elif choice == 7:  
                show()  
  
  
def menm():  
    print('============学生信息管理系统============')  
    print('---------------功能菜单---------------')  
    print('\t\t1.录入学生信息')  
    print('\t\t2.查找学生信息')  
    print('\t\t3.删除学生信息')  
    print('\t\t4.修改学生信息')  
    print('\t\t5.排序')  
    print('\t\t6.统计学生总数')  
    print('\t\t7.显示所有学生信息')  
    print('\t\t0.退出')  
    print('---------------------------------')  
  
  
# 录入学生信息  
def insert():  
    student_list = []  
    while True:  
        id = input('请输入学号(如:1001):')  
        if not id:  
            break  
        name = input('请输入姓名:')  
        if not name:  
            break  
  
    try:  
        english = int(input('请输入英语成绩:'))  
        python = int(input('请输入python成绩:'))  
        java = int(input('请输入java成绩:'))  
    except:  
        print('输入无效,不是整数类型,请重新输入')  
        continue  
    student = {  
        'id': id,  
        'name': name,  
        'english': english,  
        'python': python,  
        'java': java  
    }  
    student_list.append(student)  
    answer = input('是否继续添加?y/n\n')  
    if answer == 'y':  
        continue  
    else:  
        break  
    save(student_list)  
    print('学生信息录入完毕!!!')  
  
  
def save(lst):  
    try:  
        stu_txt = open(filename, 'a', encoding='utf-8')  
    except:  
        stu_txt = open(filename, 'w', encoding='utf-8')  
    for item in lst:  
        stu_txt.write(str(item) + '\n')  
    stu_txt.close()  
  
  
# 查找学生信息  
def search():  
    while True:  
        id = ''  
        name = ''  
        if os.path.exists(filename):  
            mode = input('1.按id查找!2.按姓名查找!:')  
            if mode == '1':  
                id = input('请输入学生id')  
            elif mode == '2':  
                name = input('请输入姓名')  
            else:  
                print('您的输入有误,请重新输入')  
                continue  
        else:  
            print('文件 filename 不存在!')  
            break  
        if id != '' or name != '':  
            with open(filename, 'r', encoding='utf-8') as file:  
                students = []  
                for item in file.readlines():  
                    d = dict(eval(item))  
                    if d['id'] == id or d['name'] == name:  
                        students.append(d)  
                    else:  
                        continue  
                show_student(students)  
                file.close()  
            answer = input('是否继续查询其他的学员信息?Y/N')  
            if answer == 'y' or answer == 'Y':  
                continue  
            else:  
                break  
        else:  
            print('您的输入不能为空')  
            continue  
  
  
def show_student(lst):  
    if not len(lst):  
        print('没有查询到学生信息,无数据显示!')  
        return  
    format_title = '{:^6}\t{:^8}\t{:^8}\t{:^8}\t{:^8}'  
    print(format_title.format('ID', '姓名', '英语成绩', 'python', 'java'))  
    format_data = '{:^6}\t{:^8}\t{:^8}\t{:^8}\t{:^8}'  
    for item in lst:  
        print(format_data.format(  
            item.get('id'),  
            item.get('name'),  
            item.get('english'),  
            item.get('python'),  
            item.get('java')  
        ))  
  
  
# 删除学生信息  
def delete():  
    while True:  
    student_id = input('请输入要删除的学生的ID:')  
    if student_id != '':  
        if os.path.exists(filename):  
            with open(filename, 'r', encoding='utf-8') as file:  
                student_old = file.readlines()  
        else:  
            student_old = []  
        flag = False  
        if student_old:  
            with open(filename, 'w', encoding='utf-8') as wfile:  
                d = {}  
                for item in student_old:  
                    d = dict(eval(item))  
                    if d['id'] != student_id:  
                        wfile.write(str(d) + '\n')  
                    else:  
                        flag = True  
                        if flag:  
                            print(f'id为{student_id}的学生信息已被删除')  
                        else:  
                            print(f'没有找到id为{student_id}的学生信息')  
        else:  
            print('无学生信息')  
            break  
        show()  
        answer = input('是否继续删除?y/n')  
        if answer == 'y' or answer == 'Y':  
            continue  
        else:  
            break  
  
  
# 修改学生信息  
def modify():  
    show()  
    # 读取了 filename文件内的内容 并 存储在 student_old  
    if os.path.exists(filename): # 判断文件 filename 是否存在  
        with open(filename, 'r', encoding='utf-8') as rfile:  
        student_old = rfile.readlines()  
    else:  
        print('文件 filename 不存在!')  
        return  
    student_id = input('请输入要修改的学员ID:')  
    with open(filename, 'w', encoding='utf-8') as wfile:  
        for item in student_old:  
            d = dict(eval(item))  
            if d['id'] == student_id:  
                print('找到学生信息,可以修他的相关信息了!')  
                while True:  
                    try:  
                        d['name'] = input('请输入姓名:')  
                        d['english'] = int(input('请输入英语成绩:'))  
                        d['python'] = int(input('请输入python成绩:'))  
                        d['java'] = int(input('请输入java成绩:'))  
                        break  
                    except:  
                        print('您的输入有误,请重新输入!!')  
                wfile.write(str(d) + '\n')  
                print('修改成功')  
            else:  
                wfile.write(str(d) + '\n')  
        wfile.close()  
        answer = input('是否继续修改的学员信息?Y/N')  
        if answer == 'y' or answer == 'Y':  
            modify()  
  
  
# 排序  
def sort():  
    while True:  
    if os.path.exists(filename):  
        sort_type = input('0.按英语排序展示!1.按python降序展示!2.按java降序展示!:')  
        sort_reverse = input('0.按降序展示!1.按升序展示!:')  
        if sort_reverse in ['0', '1'] and sort_type in ['0', '1', '2']:  
            with open(filename, 'r', encoding='utf-8') as file:  
                students = []  
                for item in file.readlines():  
                    students.append(dict(eval(item)))  
            sort_fun(students, sortArr[int(sort_type)], boolArr[int(sort_reverse)])  
            answer = input('是否继续查询其他排序信息?Y/N')  
            if answer == 'y' or answer == 'Y':  
                continue  
            else:  
                break  
        else:  
            print('输入有误,请重新输入!')  
            continue  
    else:  
        print('文件 filename 不存在!')  
        break  
  
  
def sort_fun(lst, sort_type, sort_reverse):  
    show_student(sorted(lst, key=lambda x: x[sort_type], reverse=sort_reverse))  
  
  
# 统计学生总数  
def total():  
    while True:  
        if os.path.exists(filename):  
            with open(filename, 'r', encoding='utf-8') as file:  
                students = []  
                for item in file.readlines():  
                    students.append(dict(eval(item)))  
                    print(f'一共右 { len(students) } 名学生')  
                    break  
        else:  
            print('文件 filename 不存在!')  
            break  
  
  
# 显示所有学生信息  
def show():  
    while True:  
        if os.path.exists(filename):  
            with open(filename, 'r', encoding='utf-8') as file:  
                students = []  
                for item in file.readlines():  
                    students.append(dict(eval(item)))  
                show_student(students)  
                break  
            else:  
                print('文件 filename 不存在!')  
                break  
  
  
if __name__ == '__main__':  
main()

打包

pip install PyInstaller
PyInstaller -F E:\xxx\xxx\xxx\xxx.py