Python基础 2.5 包,代码规范,案例

2.5包,代码规范,案例

2.5.1 包

  • 有2个或以上的模块有联系,他们都在同一文件夹下
  • 文件夹中有__init__.py的文件
  • 则这个文件夹就是一个包,包用于将模块文件组织起来
  • 包能有效规避模块名冲突,能提高程序的结构性和可维护性

1.创建包

  1. 同一文件夹有2个或以上的模块有联系
  2. 在该文件夹里创建__init__.py文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cvynNFHj-1610885407167)(\asset\Snipaste_2020-10-30_18-25-11.png)]

2. 导入包中模块

  • 使用 import 包名.模块名 能够导入包中的模块
  • 使用 from 包名.模块名 import...能够导入模块中的符号
  • 这样子导入是跳过了执行__init__.py文件
  • 即使是在同一包中,也要输入包名,因为默认工作路径不在包下面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s6Cr9xCl-1610885407176)(\asset\Snipaste_2020-10-30_18-24-57.png)]

from Msg.SendMsg import send_test as s
from Msg.ReceMsg import receive_test as r
r()
s()

3.__init__文件的作用

如果我们直接导入包,会发现没有作用,是因为我们之前没向__init__文件写入任何代码,而这个文件就是控制包导入文件的。

  • 包被导入时,会执行 __init__.py文件的内容
  • __init__.py 的作用:控制包的导入行为,管理模块文件
  • __init__.py文件可以上面2节2种导入方法,可以直接导入模块,或者导入模块里的工具。并且也可以改名。
  • 导入工具的时候可以不写模块名,而是包名.工具

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c7Ij604W-1610885407182)(\asset\Snipaste_2020-10-30_19-28-50.png)]

拓展
from . import 模块名  = import 模块
# .代表当前文件夹

2.5.2 PEP8代码规范

  1. 缩进使用4个空格, 空格是首选的缩进方式. Python3 不允许混合使用制表符和空格来缩进.

  2. 每一行最大长度限制在79个字符以内.

  3. 顶层函数、类的定义, 前后使用两个空行隔开.

  4. import 导入

    1. 导入建议在不同的行, 例如:

      import os
      import sys
      # 不建议如下导包
      import os, sys
      # 但是可以如下:
      from subprocess import Popen, PIPE
      
    2. 导包位于文件顶部, 在模块注释、文档字符串之后, 全局变量、常量之前. 导入按照以下顺序分组:

      1. 标准库导入
      2. 相关第三方导入
      3. 本地应用/库导入
      4. 在每一组导入之间加入空行
  5. Python 中定义字符串使用双引号、单引号是相同的, 尽量保持使用同一方式定义字符串. 当一个字符串包含单引号或者双引号时, 在最外层使用不同的符号来避免使用反斜杠转义, 从而提高可读性.

  6. 表达式和语句中的空格:

    1. 避免在小括号、方括号、花括号后跟空格.
    2. 避免在逗号、分好、冒号之前添加空格.
    3. 冒号在切片中就像二元运算符, 两边要有相同数量的空格. 如果某个切片参数省略, 空格也省略.
    4. 避免为了和另外一个赋值语句对齐, 在赋值运算符附加多个空格.
    5. 避免在表达式尾部添加空格, 因为尾部空格通常看不见, 会产生混乱.
    6. 总是在二元运算符两边加一个空格, 赋值(=),增量赋值(+=,-=),比较(==,<,>,!=,<>,<=,>=,in,not,in,is,is not),布尔(and, or, not
  7. 避免将小的代码块和 if/for/while 放在同一行, 要避免代码行太长.

    if foo == 'blah': do_blah_thing()
    for x in lst: total += x
    while t < 10: t = delay()
    
  8. 永远不要使用字母 ‘l’(小写的L), ‘O’(大写的O), 或者 ‘I’(大写的I) 作为单字符变量名. 在有些字体里, 这些字符无法和数字0和1区分, 如果想用 ‘l’, 用 ‘L’ 代替.

  9. 类名一般使用首字母大写的约定.

  10. 函数名应该小写, 如果想提高可读性可以用下划线分隔.

  11. 如果函数的参数名和已有的关键词冲突, 在最后加单一下划线比缩写或随意拼写更好. 因此 class_ 比 clss 更好.(也许最好用同义词来避免这种冲突).

  12. 方法名和实例变量使用下划线分割的小写单词, 以提高可读性.

2.5.3 应用 学生名片信息管理系统 面向对象版

1.先回忆并且理清面向对象版的逻辑

1.1 存储学生信息的格式
"""
之前我们用学生空列表存储,每个学生用字典的形式嵌套
那么现在我们同样使用空列表存储,不同的是列表里存储的是对象。[学生对象1,学生对象2,····]
对象之前我们要先有类,才能进行实现
"""


class Student(object):
    def __init__(self, _name, _age, _tel):
        self.name = _name
        self.age = _age
        self.tel = _tel


student_list = []
stu1 = Student("Tom", 19, 12345677448)
# stu2·······

student_list.append(stu1)

1.2 实现对象列表的增删改查
'''
存储形式有了,接下来就是分析要如何进行增,删,改,查
'''
# 学生对象列表的增
add_name = input("请输入学生名字:")
add_age = input("请输入学生年龄:")
add_tel = input("请输入学生电话号澳门:")
# 同样进行一次判断 是否重名
for obj in student_list:
    if obj.name == add_name:
        print("已经有该学生信息,跳出")
        break
else:
    stu = Student(add_name, add_age, add_tel)
    student_list.append(stu)
# 学生对象列表的查
for obj in student_list:
    print("表头")
    print(obj)
# 指定学生对象的查
check_name = input("请输入要查早的学生姓名:")
for obj in student_list:
    if obj.name == check_name:
        print("表头")
        print(obj)
else:
    print("查无此学生")
# 学生列表的改
edit_name = input("请输入要改的学生姓名:")
for obj in student_list:
    if edit_name == obj.name:
        pass
# 直接进行赋值更改
else:
    print("查无此姓名")
# 学生列表的删
del_name = input("请输入要删除的学生姓名:")
for obj in student_list:
    if del_name == obj.name:
        student_list.remove(obj)
else:
    print("查无此学生,删除失败")
1.3 实现对文件的操作
'''
增删改查进行完我们需要读取和存储这俩文件操作
对象是不能直接存储进文件的,我们需要把它改成字典再转成字符串才能写入
'''
# 首先进行文件的写入
user_list = []
for obj in student_list:
    # 这里可以在学生类里多增添一个方法,返回字典
    student_dict = obj.to_dict()
    # 转化后给字典增添进新列表
    user_list.append(student_dict)
# 之后将完整列表转为字符串 
list_str = str(user_list)
with open("stu.txt", "w")as f:
    f.write(list_str)
# 相反的 我们需要一个读取的操作
with open("stu.txt", "r")as f:
    list_str = f.read()
# 将读取的字符串重新转为字典嵌套列表的格式
user_list = eval(list_str)
# 然后遍历列表重新转化为对象加进去原来的列表
for student_dict in user_list:
    stu = Student(student_dict.name, student_dict.age, student_dict.tel)
    student_list.append(stu)

2.把主逻辑学生管理系统也做成类

2.1 主面板逻辑
class ManageStuSys(object):

    def __init__(self):
        self.user_list = []

    # 简陋表头作为一个静态方法 快速调用
    @staticmethod
    def table_top():
        print("姓名\t\t年龄\t\t电话号码")

    # 菜单不需要调用任何类属性和实例熟悉,故设为静态方法
    @staticmethod
    def menu():
        print("=" * 10, "学生名片管理系统", "=" * 10)
        print("1.添加学生信息")
        print("2.查询所有学生信息")
        print("3.查询指定学生信息")
        print("4.修改指定学生信息")
        print("5.删除指定学生信息")
        print("6.保存档案")
        print("7.读取档案")
        print("8.退出系统")
        print("=" * 40)

    def main(self):
        try:
            self.load_init()
        except Exception as read_e:
            print("发生错误!,错误信息如下:文件不存在\n", read_e)
        finally:
            while True:
                self.menu()
                try:
                    user_select = input("请输入需要选择的功能:")
                    if user_select == '1':
                        print("添加学生信息")
                        self.add_stu_info()
                    elif user_select == '2':
                        print("查询所有学生信息")
                        self.check_all_stu()
                    elif user_select == '3':
                        print("查询指定学生信息")
                        self.check_stu()
                    elif user_select == '4':
                        print("编辑指定学生信息")
                        self.edit_stu()
                    elif user_select == '5':
                        print("删除指定学生信息")
                        self.del_stu()
                    elif user_select == '6':
                        save_file = input("请输入要保存的文件名:")
                        self.save_info(save_file)
                    elif user_select == '7':
                        load_file = input("请输入要读取的文件名:")
                        self.load_info(load_file)
                    elif user_select == '8':
                        print("退出学生名片管理系统")
                        break
                    else:
                        raise MenuInputError(user_select)
                except Exception as e:
                    print("发生错误,错误信息为:", e)
2.2 学生信息的增
# 增添学生信息的面向对象版

    def add_stu_info(self):
        _name = input("请输入学生姓名:")
        try:
            _age = input("请输入学生年龄:")
            if not 0 < int(_age) < 100:
                raise AgeError(_age)
            _tel = input("请输入学生电话号码:")
            if len(_tel) != 11:
                raise TelError(_tel)
        except Exception as e:
            print("输入有错误,错误信息为:", e)
        else:
            if self.is_valid_stu(_name):
                print("系统已存在该学生信息,不需要重复添加")
            else:
                stu = Student(_name, _age, _tel)
                self.user_list.append(stu)
                print("添加成功")
2.3 学生信息的查
    # 查询所有学生信息的面向对象版
    def check_all_stu(self):
        if not self.user_list:
            print("系统内还没有学生信息,请读取档案或者手动增加学生信息")
        else:
            self.table_top()
            for obj in self.user_list:
                print(obj)

    # 查询单独 或者 部分学生信息的面向对象版
    def check_stu(self):
        check_name = input("请输入想查询的学生姓名:")
        for obj in self.user_list:
            if obj.name == check_name:
                print("查询到该学生信息如下")
                self.table_top()
                print(obj)
                break
        else:
            print("学生档案里无此学生的相关信息,请重新确认")
2.5 学生信息的删除
# 删除指定的学生信息
    def del_stu(self):
        del_name = input("请输入想删除的学生姓名:")
        for obj in self.user_list:
            if obj.name == del_name:
                print("查询到该学生信息如下")
                self.table_top()
                print(obj)
                self.user_list.remove(obj)
                print("该学生信息已删除")
                break
        else:
            print("学生档案里无此学生的相关信息,请重新确认")
2.5 学生信息的删改
# 编辑指定的学生信息
    def edit_stu(self):
        edit_name = input("请输入要修改的学生名字:")
        for obj in self.user_list:
            if obj.name == edit_name:
                print("查到此学生")
                print("学生信息如下\n")
                self.table_top()
                print(f"{obj.name}\t\t{obj.age}\t\t{obj.tel}")
                edit_name = input("请输入要更改的学生名字:")
                for o_obj in self.user_list:
                    if edit_name == o_obj.name and edit_name != obj.name:
                        print("重新输入的名字和库里已有的学生信息重复了,请重新输入")
                        break
                else:
                    edit_age = input("请输入要更改的学生年龄:")
                    edit_tel = input("请输入要更改的学生电话号码:")
                    try:
                        if not 0 < int(edit_age) < 100:
                            raise AgeError(edit_age)
                        if len(edit_tel) != 11:
                            raise TelError(edit_tel)
                    except Exception as e:
                        print("发生错误,错误信息为:", e)
                    else:
                        obj.name = edit_name
                        obj.age = edit_age
                        obj.tel = edit_tel
                        print("修改完成")
                break
        else:
            print("学生档案里无此学生的相关信息,请重新确认")
2.6 文件操作
# 做保存文件的对象版
    def save_info(self, save_file):
        user_dict_list = []
        for obj in self.user_list:
            user_dict_list.append(obj.to_dict())
        # 把对象列表,转换成字典列表,然后再写入文件中
        if os.path.exists(save_file):
            print("已有此文件,请问要覆盖吗?", end="")
            user_sw = input("(yes or no):")
            if user_sw == 'no':
                return
            else:
                print("覆盖该文件")
        with open(save_file, "w")as f:
            f.write(str(user_dict_list))
            print("写入成功")

    # 做开程序的时候读取文件的对象版
    def load_init(self):
        with open("stu_info.config", "r")as f:
            user_dict_list = eval(f.read())
            for user_dict in user_dict_list:
                stu = Student(user_dict['name'], user_dict['age'], user_dict['tel'])
                self.user_list.append(stu)
        print("读取完成")

    # 做一个手动读取档案的对象版
    def load_info(self, load_file):
        try:
            with open(load_file, "r")as f:
                user_dict_list = eval(f.read())
                for user_dict in user_dict_list:
                    stu = Student(user_dict['name'], user_dict['age'], user_dict['tel'])
                    self.user_list.append(stu)
            print("读取完成")
        except Exception as e:
            print("发生错误,错误消息为:找不到文件", e)

3. 用try…except…实现自定义的报错

import os

from Stu.stu_module import Student
from Stu.input_error import AgeError, TelError, MenuInputError, ReadNoneError


class ManageStuSys(object):
    save_op = 0

    def __init__(self):
        self.user_list = []

    # 简陋表头作为一个静态方法 快速调用
    @staticmethod
    def table_top():
        print("姓名\t\t年龄\t\t电话号码")

    # 菜单不需要调用任何类属性和实例熟悉,故设为静态方法
    @staticmethod
    def menu():
        print("=" * 10, "学生名片管理系统", "=" * 10)
        print("1.添加学生信息")
        print("2.查询所有学生信息")
        print("3.查询指定学生信息")
        print("4.修改指定学生信息")
        print("5.删除指定学生信息")
        print("6.保存档案")
        print("7.读取档案")
        print("8.退出系统")
        print("=" * 40)

    def main(self):
        try:
            self.load_init()
        except Exception as read_e:
            print("发生错误!,错误信息如下:文件不存在\n", read_e)
        finally:
            while True:
                self.menu()
                try:
                    user_select = input("请输入需要选择的功能:")
                    if user_select == '1':
                        print("添加学生信息")
                        self.add_stu_info()
                    elif user_select == '2':
                        print("查询所有学生信息")
                        self.check_all_stu()
                    elif user_select == '3':
                        print("查询指定学生信息")
                        self.check_stu()
                    elif user_select == '4':
                        print("编辑指定学生信息")
                        self.edit_stu()
                    elif user_select == '5':
                        print("删除指定学生信息")
                        self.del_stu()
                    elif user_select == '6':
                        save_file = input("请输入要保存的文件名:")
                        self.save_info(save_file)
                        self.save_op += 1
                    elif user_select == '7':
                        load_file = input("请输入要读取的文件名:")
                        self.load_info(load_file)
                    elif user_select == '8':
                        if self.check_save():
                            print("退出学生名片管理系统")
                            break
                    else:
                        raise MenuInputError(user_select)
                except Exception as e:
                    print("发生错误,错误信息为:", e)

    # 判断输入学生名字是否在表里是,实际上因为几次判断重复名字的需求都不是一致的,有的只是需求返回布尔,有的还需要同时返回遍历得到的数据
    # 想太多了 只要我2个都返回同样的值,就可以了!运用了函数可以返回组包值的用法。多个数值返回的是一个元组。
    def is_valid_stu(self, check_name):
        for obj in self.user_list:
            if obj.name == check_name:
                return True, obj
        else:
            return False, ''

    # 增添学生信息的面向对象版

    def add_stu_info(self):
        _name = input("请输入学生姓名:")
        try:
            _age = input("请输入学生年龄:")
            if not 0 < int(_age) < 100:
                raise AgeError(_age)
            _tel = input("请输入学生电话号码:")
            if len(_tel) != 11:
                raise TelError(_tel)
        except Exception as e:
            print("输入有错误,错误信息为:", e)
        else:
            if self.is_valid_stu(_name)[0]:
                print("系统已存在该学生信息,不需要重复添加")
            else:
                stu = Student(_name, _age, _tel)
                self.user_list.append(stu)
                print("添加成功")

    # 查询所有学生信息的面向对象版
    def check_all_stu(self):
        if not self.user_list:
            print("系统内还没有学生信息,请读取档案或者手动增加学生信息")
        else:
            self.table_top()
            for obj in self.user_list:
                print(obj)

    # 查询单独 或者 部分学生信息的面向对象版
    def check_stu(self):
        check_name = input("请输入想查询的学生姓名:")
        if self.is_valid_stu(check_name)[0]:
            self.table_top()
            print(self.is_valid_stu(check_name)[1])
        else:
            print("学生档案里无此学生的相关信息,请重新确认")

    # 删除指定的学生信息
    def del_stu(self):
        del_name = input("请输入想删除的学生姓名:")
        if self.is_valid_stu(del_name)[0]:
            temp_obj = self.is_valid_stu(del_name)[1]
            print("查询到该学生信息如下")
            self.table_top()
            print(temp_obj)
            self.user_list.remove(temp_obj)
            print("该学生信息已删除")
        else:
            print("学生档案里无此学生的相关信息,请重新确认")

    # 编辑指定的学生信息
    def edit_stu(self):
        edit_name = input("请输入要修改的学生名字:")
        if self.is_valid_stu(edit_name)[0]:
            edit_name = input("请输入要更改的学生名字:")
            for o_obj in self.user_list:
                if edit_name == o_obj.name and edit_name != self.is_valid_stu(edit_name)[1].name:
                    print("重新输入的名字和库里已有的学生信息重复了,请重新输入")
                    break
            else:
                edit_age = input("请输入要更改的学生年龄:")
                edit_tel = input("请输入要更改的学生电话号码:")
                try:
                    if not 0 < int(edit_age) < 100:
                        raise AgeError(edit_age)
                    if len(edit_tel) != 11:
                        raise TelError(edit_tel)
                except Exception as e:
                    print("发生错误,错误信息为:", e)
                else:
                    temp_obj = self.is_valid_stu(edit_name)[1]
                    temp_obj.name = edit_name
                    temp_obj = edit_age
                    temp_obj.tel = edit_tel
                    print("修改完成")
        else:
            print("学生档案里无此学生的相关信息,请重新确认")

    # 做保存文件的对象版
    def save_info(self, save_file):
        user_dict_list = []
        for obj in self.user_list:
            user_dict_list.append(obj.to_dict())
        # 把对象列表,转换成字典列表,然后再写入文件中
        if os.path.exists(save_file):
            print("已有此文件,请问要覆盖吗?", end="")
            user_sw = input("(yes or no):")
            if user_sw == 'no':
                return
            else:
                print("覆盖该文件")
        with open(save_file, "w")as f:
            f.write(str(user_dict_list))
            print("写入成功")
            self.save_op += 1

    # 做开程序的时候读取文件的对象版
    def load_init(self):
        with open("stu_info.config", "r")as f:
            user_dict_list = eval(f.read())
            for user_dict in user_dict_list:
                stu = Student(user_dict['name'], user_dict['age'], user_dict['tel'])
                self.user_list.append(stu)
        print("读取完成")

    # 做一个手动读取档案的对象版
    def load_info(self, load_file):
        try:
            with open(load_file, "r")as f:
                if not f.read():
                    raise ReadNoneError
                else:
                    # 注意 因为第一次判断已经读取了全部,导致光标在最后所以必须回移光标不然后面是铁定读成空
                    f.seek(0)
                    user_dict_list = eval(f.read())
                    for user_dict in user_dict_list:
                        stu = Student(user_dict['name'], user_dict['age'], user_dict['tel'])
                        self.user_list.append(stu)
                    print("读取完成")
        except Exception as e:
            print("发生错误,错误消息为:", e)

    def check_save(self):
        if self.save_op < 1:
            user_sw = input("还没保存过,请问是否先保存?(yes or no): ")
            if user_sw == 'yes':
                return False
            elif user_sw == 'no':
                return True
            else:
                print("输入错误")
                return True


if __name__ == '__main__':
    mss = ManageStuSys()
    mss.main()

4.模块化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值