重构父类__init__方法

#!/usr/bin/env python3
# author:Alnk(李成果)
# 需求:Dog类要新增一个实例属性,但是Cat类不需要 class Animal(object):
def __init__(self, name, age):
self.name = name
self.age = age def run(self):
print('run...') def sleep(self):
print('sleep...') class Cat(Animal):
pass class Dog(Animal):
def __init__(self, name, age, kind):
super().__init__(name, age) # 执行父类方法
self.kind = kind t = Dog('tom', 23, '狗子')
print(t.kind) c = Cat("jerry", 1)
print(c.name)

封装

封装-基本概念

#!/usr/bin/env python3
# author: Alnk(李成果) """
封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式
好处:将变化隔离、便于使用、提高重用性、提高安全性
封装原则:将不需要对外提供的内容都隐藏起来、把属性都隐藏,提供公共方法对其访问 使用封装有好处:
1、良好的封装能够减少耦合
2、类内部的结构可以自由修改
3、可以对成员进行更精确的控制
4、隐藏信息,隐藏实现细节 用法:
私有化变量(属性)
私有化方法
property属性
classmethod方法
staticmethod方法
"""

封装-实例私有属性

#!/usr/bin/env python3
# author: Alnk(李成果) # 一般属性
class Student(object): def __init__(self, name, age):
self.name = name # 一般属性
self.age = age t = Student('tom', 24)
print(t.age) # 可以直接在类的外面访问
print("----------------- 1 ----------------") # 私有化属性 __变量
# 保护数据,不让类外部直接访问
class Student(object): def __init__(self, name, age):
self.__name = name # 实例私有属性:__变量
self.__age = age def print_age(self):
print('年龄:%s' % self.__age) # 私有化属性可以在类的内部访问 t = Student('tom', 24)
# print(t.age) # 不可以直接在类的外部访问
# print(t.__dict__["_Student__age"]) # python中还是有方法可以访问实例的私有属性的
t.print_age()
print("----------------- 2 ----------------") # 需求:要在类的外部访问私有化属性。
# 开接口:能在外部修改类的私有属性,但是能更加精确的控制
# 好处:可以更加精确的控制数据
class Student(object): def __init__(self, name, age):
self.__name = name # 私有属性
self.__age = age def get_age(self): # 提供可读属性接口
return self.__age def set_age(self, new_age): # 提供可写属性接口
if isinstance(new_age, int) and (0 < new_age < 120):
self.__age = new_age
else:
# raise ValueError("年龄不符合条件") # 直接让程序报错,停止程序
print("年龄不符合条件") t = Student('tom', 24)
# 可读接口
print(t.get_age()) # 可写接口
t.set_age(80)
print(t.get_age())
t.set_age(1000)
print(t.get_age())

封装-实例私有属性存储关系

#!/usr/bin/env python3
# author: Alnk(李成果) # 一般属性存储关系
class Student(object):
x = 100
def __init__(self, name, age):
self.name = name # 一般属性
self.age = age tom = Student('tom', 24)
print(tom.name) # tom # __dict__ 打印tom实例对象的所有变量
print(tom.__dict__) # {'name': 'tom', 'age': 24} tom.sex = 'F'
print(tom.__dict__) # {'name': 'tom', 'age': 24, 'sex': 'F'}
print("----------------- 1 ----------------") # 实例私有属性存储关系
class Student(object): def __init__(self, name, age):
self.__name = name # 私有属性
self.__age = age def get_age(self): # 提供可读属性接口
return self.__age def set_age(self, new_age): # 提供可写属性接口
if isinstance(new_age, int) and (0 < new_age < 120):
self.__age = new_age
else:
print("年龄不符合条件") # 1 外部可以控制私有属性,强烈不建议使用,不规范
tom = Student('tom', 24)
print(tom.__dict__) # 私有属性 "_当前类名__私有变量":实际值 {'_Student__name': 'tom', '_Student__age': 24}
tom.sex = 'F'
print(tom.__dict__) # {'_Student__name': 'tom', '_Student__age': 24, 'sex': 'F'} # 直接访问私有属性
print(tom._Student__name) # tom # 直接修改私有属性,但是不建议这么用,不规范,私有变量不建议更改
# 结论:python的私有属性\变量并不是真正的私有属性\变量,还是有方法可以控制的。
# 但是,不建议使用,不规范
tom._Student__age = 10000
print(tom.get_age()) # 10000
print("----------------- 2 ----------------") # 2
tom = Student('tom', 24)
# 相当于在tom的实例内存空间追加了一个变量 __age = 1000
tom.__age = 1000 print(tom.__age) # 1000
print(tom.__dict__) # {'_Student__name': 'tom', '_Student__age': 24, '__age': 1000}

封装-类私有属性

#!/usr/bin/env python3
# author: Alnk(李成果)
# 类属性的私有化
# 私有属性不仅适用于实例属性,也适用于类属性 # 一般类 属性\变量
class Parent(object):
x = 100 # 一般类 属性\变量 def f1(self):
pass p1 = Parent() # 实例化
print(p1.x) # 100
print(p1.__dict__) # {} 这里空字典的原因是:实例空间没有实例属性 # 类对象
print(Parent.x) # 100 类属性
print(Parent.__dict__) # {..., 'x': 100, 'f1': <function Parent.f1 at 0x7fa1c92eca60>, ...}
print("----------------- 1 ----------------") # 类 属性\变量 的私有化
class Parent(object):
__x = 100 def f1(self):
pass p1 = Parent()
# print(p1.__x) # 类私有属性,外部不能直接访问
# print(Parent.__x) # 类私有属性,外部不能直接访问
print(Parent.__dict__) # {'_Parent__x': 100, 'f1': <function Parent.f1 at 0x7f9ed82e19d8>,} # 可以通过这种方法访问,但是强烈建议不要这么使用
print(Parent._Parent__x) # 100
print(Parent.__dict__["_Parent__x"]) # 100

封装-私有属性不能继承

#!/usr/bin/env python3
# author:Alnk(李成果)
# 私有属性不能继承 class A:
__x = 100 # 类私有属性
y = 200 # 类一般属性 def __init__(self):
self.__name = "alnk"
self.age = 14 class B(A):
z = 300 b = B() # 类一般属性的继承
print(b.z) # 300
print(b.y) # 200 # 类私有属性不能继承
# print(b.__x) # 报错 AttributeError: 'B' object has no attribute '__x' # 当然有其他方法也可以访问
print(b._A__x) # 100 不建议这么做
print("-------------- 1 ---------------------") # 实例一般属性的继承
print(b.age) # 14 # 实例私有属性不能继承
# print(b.__name) # 报错 AttributeError: 'B' object has no attribute '__name' # 当然有其他方法也可以访问
print(b._A__name) # alnk 不建议这么做

封装-下划线

#!/usr/bin/env python3
# author: Alnk(李成果) """
单下划线、双下划线、头尾双下划线说明
__foo__: 定义的是特殊方法,一般是系统定义名字 ,类似 __init__() 之类的
_foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问(约定成俗,不限语法)
__foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了 变量 public 公共的
_变量 protected 受保护的
__变量 private 私有的
""" class A(object):
_x = 10
__y = 20
z = 30 a = A() # 10 约定成俗,不限语法
print(a._x) # 10
print(a.z) # 30 # print(a.__y) # 报错
print(a._A__y) # 20
print(a.__dict__) # 实例空间变量 {}
print(A.__dict__) # 类空间变量 {'_x': 10, '_A__y': 20, 'z': 30}
print(A.__dict__["_A__y"]) # 20

封装-私有方法不能继承

#!/usr/bin/env python3
# author:Alnk(李成果)
# 在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为私有的
# 私有方法不能继承 # 正常情况
class A(object):
def fa(self):
print('from A') def test(self):
self.fa() class B(A):
pass b = B()
b.fa() # from A
b.test() # from A
print("---------------- 1 -----------------------") # 把 fa 定义为私有的,即 __fa
class A(object):
def __fa(self): # 在定义的时候就变形为 _A__fa
print('from A') def test(self):
self.__fa() # 只会以自己所在的类为准,基调用 _A__fa class B(A):
# def __fa(self):
# print('from B')
pass b = B()
b.test() # from A # b.__fa() # 报错 AttributeError: 'B' object has no attribute '__fa'
b._A__fa() # from A

封装-property属性

#!/usr/bin/env python3
# author:Alnk(李成果) # 什么是特性property
# property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值
# 把一个方法属性化 # 为什么要用property?
# 将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,
# 这种特性的使用方式遵循了统一访问的原则在C++里一般会将所有的数据都设置为私有的,
# 然后提供set和get方法(接口)去设置和获取,在python中通过property方法可以实现 class People(object):
def __init__(self, name, weight, height):
self.name = name
self.wight = weight
self.height = height @property # 改变一个方法的调用方式
def bmi(self):
return self.wight / (self.height**2) def test(self):
print("in test") p1 = People('tom', 75, 1.85) p1.test() # 正常的调用一个方法 print(p1.bmi) # 改变一个方法的调用方式

封装-classmethod方法

#!/usr/bin/env python3
# author:Alnk(李成果)
# classmethod 修饰符对应的函数不需要实例化,不需要 self 参数
# 但第一个参数需要是表示自身类的 cls 参数,可以来调用类的属性,类的方法,实例化对象等 class Student(object):
school = '清华大学' def __init__(self, name, age):
self.name = name
self.age = age def run(self):
print('%s is running... ' % self.name) @classmethod # 类方法
def foo(cls):
print(cls) # 和 Student 的内存地址相同
print('cls', id(cls)) # 是同一个内存地址
print("student", id(Student)) # 是同一个内存地址
print('学校名称:%s' % cls.school) # 实例方法是由实例对象调用的,不能直接由类调用
tom = Student('tom', 23)
jerry = Student('jerry', 24)
tom.run()
jerry.run()
# Student.run() # TypeError: run() missing 1 required positional argument: 'self'
print("------------- 1 -------------------") # 类方法,可以直接由类调用
Student.foo()
print("------------- 2 -------------------") # 当然,实例也可以调用类方法
tom.foo()

封装-staticmethod方法

#!/usr/bin/env python3
# author: Alnk(李成果) # 实例方法: 涉及到实例变量的时候使用
# 类方法classmethod: 涉及到类变量的时候使用
# 静态方法staticmethod: 不涉及到类变量和实例变量的时候使用 class Student(object):
school = '清华大学' def __init__(self, name, age):
self.name = name
self.age = age # 一般方法
def run(self):
print('%s is running... ' % self.name) # 类方法
@classmethod
def foo(cls):
print('学校名称:%s' % cls.school) # 静态方法
@staticmethod
def calculation(x, y): # 没有self了
return x * y tom = Student('tom', 26) # 一 调用静态方法
# 1,实例调用静态方法
ret = tom.calculation(2, 8)
print(ret) # 2,类调用静态方法
ret1 = Student.calculation(3, 6) # 不需要传入self了
print(ret1)
print("---------------- 1 ----------------------") # 二 调用类方法
Student.foo()
tom.foo()
print("---------------- 1 ----------------------") # 三 调用一般方法
tom.run()
# Student.run() # TypeError: run() missing 1 required positional argument: 'self'

归一化设计

#!/usr/bin/env python3
# author: Alnk(李成果) # 归一化设计
# 做成一个接口
lis = [1, 2, 3]
dic = {1: 2, 3: 4, 5: 6}
s = 'hello' # 需求
# 求一个序列对象的长度
print(lis.__len__())
print(dic.__len__())
print(s.__len__())
print("---------------- 1 ------------------------") # 归一接口:len()
print(len(lis))
print(len(dic))
print(len(s))
print("---------------- 2 ------------------------") # 支付接口归一化
class Payment(object):
def __init__(self, name, money):
self.name = name
self.money = money class AliPay(Payment):
def pay(self):
print('%s通过支付宝消费了%s元' % (self.name, self.money)) class WeChatPay(Payment):
def pay(self):
print('%s通过微信消费了%s元' % (self.name, self.money)) def pay_func(pay_obj): # 接口归一
pay_obj.pay() a = AliPay('tom', 100)
w = WeChatPay('jerry', 200) # 调用归一接口
pay_func(a)
pay_func(w)
print("---------------- 3 ------------------------") # 支付接口归一化,规范的写法
"""
规范化方法
支付宝 微信 银行卡 nfc支付
同事协作之间的代码规范问题 规定: Payment 就是一个规范类,这个类存在的意义不在于实现实际的功能,而是为了约束所有的子类必须实现pay的方法
Payment : 抽象类
pay = Payment() # 抽象类: 不能实例化
抽象类主要就是作为基类/父类,来约束子类中必须实现的某些方法
抽象类的特点:
必须在类定义的时候指定 metaclass = ABCMeta
必须在要约束的方法上方加上 @abstractmethod 方法
""" from abc import ABCMeta, abstractmethod # (抽象方法) class Payment(metaclass=ABCMeta): # metaclass 元类 metaclass = ABCMeta表示Payment类是一个规范类
def __init__(self, name, money):
self.name = name
self.money = money @abstractmethod # 当子类继承的时候,必须重构pay方法,不然在子类实例化的时候就报错
def pay(self):
pass class AliPay(Payment):
def pay(self):
print('%s通过支付宝消费了%s元' % (self.name, self.money)) class WeChatPay(Payment):
def pay(self):
print('%s通过微信消费了%s元' % (self.name, self.money)) def pay_func(pay_obj): # 接口归一
pay_obj.pay() a = AliPay('tom', 2000)
w = WeChatPay('jerry', 4000) # 调用归一接口
pay_func(a)
pay_func(w)

多态

#!/usr/bin/env python3
# author: Alnk(李成果)
# 多态
# 第一种解释
# 多态:指的是一类事物有多种形态
# 动物有多种形态:人,狗,猪
import abc class Animal(metaclass=abc.ABCMeta): # 同一类事物:动物
@abc.abstractmethod
def talk(self):
pass class People(Animal): # 动物形态之一:人
def talk(self):
print('say hello') class Dog(Animal): # 动物的形态之二:狗
def talk(self):
print('say 旺旺旺') class Pig(Animal): # 动物的形态之三:猪
def talk(self):
print('say 嗷嗷嗷') # 文件有多种形态:文本文件,可执行文件
class File(metaclass=abc.ABCMeta): # 同一类事物:文件
@abc.abstractmethod
def click(self):
pass class Text(File): # 文件的形态之一:文本文件
def click(self):
print('open file') class ExeFile(File): # 文件的形态之二:可执行文件
def click(self):
print('execute file') # 什么是多态动态绑定(在继承的背景下使用时,有时也称为多态性)
# 多态性是指在不考虑实例类型的情况下使用实例
# 在面向对象方法中一般是这样表述多态性
# 向不同的对象发送同一条消息
# (obj.func(): 是调用了obj的方法func,又称为向obj发送了一条消息func),不同的对象在接收时会产生不同的行为(即方法)
# 也就是说,每个对象可以用自己的方式去响应共同的消息。所谓消息,就是调用函数,不同的行为就是指不同的实现,即执行不同的函数
# 比如:老师.下课铃响了(),学生.下课铃响了(),老师执行的是下班操作,学生执行的是放学操作,虽然二者消息一样,但是执行的效果不同 # 多态性
peo = People()
dog = Dog()
pig = Pig() # peo、dog、pig都是动物,只要是动物肯定有talk方法
# 于是我们可以不用考虑它们三者的具体是什么类型,而直接使用
peo.talk()
dog.talk()
pig.talk()
print("--------------------------- 1 ---------------------------------") # 更进一步,我们可以定义一个统一的接口来使用
def func(obj):
obj.talk() func(peo)
func(dog)
func(pig)
print("--------------------------- 2 ---------------------------------") # 多态
# 第二种解释
# from abc import ABCMeta, abstractmethod
#
#
# class Payment(metaclass=ABCMeta):
# def __init__(self, name, money):
# self.money = money
# self.name = name
#
# @abstractmethod
# def pay(self):
# pass
#
#
# class AliPay(Payment):
# def pay(self):
# # 支付宝提供了一个网络上的联系渠道
# print('%s通过支付宝消费了%s元' % (self.name, self.money))
#
#
# class WeChatPay(Payment):
# def pay(self):
# # 支付宝提供了一个网络上的联系渠道
# print('%s通过微信消费了%s元' % (self.name, self.money))
#
#
# class ApplePay(Payment):
# def pay(self):
# print('%s通过apple消费了%s元' % (self.name, self.money))
#
#
# al = AliPay("tom", 100)
# w = WeChatPay('tom', 200)
# ap = ApplePay("jerry", 1000)
#
#
# def pay_func(pay_obj):
# pay_obj.pay()
# # pay_func(al)
# pay_func(w)
# pay_func(ap) # 多态的概念
# 要理解什么是多态,我们首先要对数据类型再作一点说明
# 当我们定义一个class的时候,我们实际上就定义了一种数据类型
# 我们定义的数据类型和Python自带的数据类型,比如str、list、dict没什么两样 # a = list() # a是list类型
# b = Animal() # b是Animal类型
# c = Dog() # c是Dog类型 # 判断一个变量是否是某个类型可以用isinstance()判断:
# >>> isinstance(a, list)
# True
# >>> isinstance(b, Animal)
# True
# >>> isinstance(c, Dog)
# True 
# 看来a、b、c确实对应着list、Animal、Dog这3种类型。
# 但是等等,试试:
# >>> isinstance(c, Animal)
# True
# 看来c不仅仅是Dog,c还是Animal!
# 不过仔细想想,这是有道理的,因为Dog是从Animal继承下来的,
# 当我们创建了一个Dog的实例c时,我们认为c的数据类型是Dog没错,但c同时也是Animal也没错,Dog本来就是Animal的一种!
# 所以,在继承关系中,如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类
# 但是,反过来就不行:
# >>> b = Animal()
# >>> isinstance(b, Dog)
# False
# Dog可以看成Animal,但Animal不可以看成Dog
# 所以,上面的支付的例子,如果我们再定义一个ApplePay类型,也从Payment类派生:
# class ApplePay(Payment):
# def pay(self):
# print('%s通过苹果支付消费了%s元'%(self.name,self.money))
#
# ap=ApplePay("lisa",800) # 你会发现,新增一个Payment的子类,不必对pay()做任何修改,
# 实际上,任何依赖Payment作为参数的函数或者方法都可以不加修改地正常运行,原因就在于多态。 # 多态的好处就是,当我们需要传入AliPay、WeChatPay、ApplePay……时,
# 我们只需要接收Payment类型就可以了,因为AliPay、WeChatPay、ApplePay……都是Payment类型,
# 然后,按照Payment类型进行操作即可。由于Payment类型有pay()方法,
# 因此,传入的任意类型,只要是Payment类或者子类,就会自动调用实际类型的pay()方法,这就是多态的意思 # 对于一个变量,我们只需要知道它是Payment类型,无需确切地知道它的子类型,
# 就可以放心地调用pay()方法,而具体调用的pay()方法是作用在AliPay、WeChatPay、ApplePay哪个类对象上,
# 由运行时该对象的确切类型决定,这就是多态真正的威力:调用方只管调用,不管细节,
# 而当我们新增一种Payment的子类时,只要确保pay()方法编写正确,不用管原来的代码是如何调用的
# 这就是著名的“开闭”原则:
# 对扩展开放:允许新增Payment子类;
# 对修改封闭:不需要修改依赖Payment类型的pay()等函数

鸭子类型

#!/usr/bin/env python3
# author: Alnk(李成果)
# 鸭子类型
from abc import ABCMeta, abstractmethod class Payment(metaclass=ABCMeta): # Payment看做是一只鸭子
def __init__(self, name, money):
self.name = name
self.money = money @abstractmethod
def pay(self):
pass class AliPay(Payment):
def pay(self):
print('%s通过支付宝消费了%s元' % (self.name, self.money)) class WeChatPay(Payment):
def pay(self):
print('%s通过微信消费了%s元' % (self.name, self.money)) class CardPay(object): # 像鸭子
def __init__(self, name, money):
self.money = money
self.name = name def pay(self):
print('%s通过银联卡支付消费了%s元' % (self.name, self.money)) def pay_func(pay_obj): # 传入的值只要像鸭子就行
pay_obj.pay() a = AliPay('tom', 100)
w = WeChatPay('jerry', 200)
pay_func(a)
pay_func(w) # 调用鸭子的接口
cp = CardPay("lisa", 1000)
pay_func(cp) # 对于静态语言(例如Java)来说,如果需要传入Payment类型,则传入的对象必须是Payment类型或者它的子类,
# 否则,将无法调用pay()方法。 # 对于Python这样的动态语言来说,则不一定需要传入Payment类型。我们只需要保证传入的对象有一个pay()方法就可以了 # 这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,
# 那它就可以被看做是鸭子

练习题

需求

需求:
从“学生选课系统” 这几个字就可以看出来,我们最核心的功能其实只有 选课 角色:
学生、管理员、讲师 功能:
登陆 : 管理员和学生都可以登陆,且登陆之后可以自动区分身份
选课 : 学生可以自由的为自己选择课程
创建用户 : 选课系统是面向本校学生的,因此所有的用户都应该由管理员完成
查看选课情况 :每个学生可以查看自己的选课情况,而管理员应该可以查看所有学生的信息 工作流程:
登陆 :用户输入用户名和密码
判断身份 :在登陆成果的时候应该可以直接判断出用户的身份 是学生、讲师还是管理员 学生用户 :对于学生用户来说,登陆的工作几乎不变
1、查看所有课程
2、选择课程
3、查看所选课程
4、退出程序 管理员用户:管理员用户也可以做更多的事情
1、创建课程
2、创建学生学生账号
3、查看所有课程
4、查看所有学生
5、查看所有学生的选课情况
6、创建讲师
7、为讲师指定班级
8、创建班级
9、为学生指定班级
10、退出程序 讲师用户 :对于讲师用户来说,可以完成的功能如下
1、查看所有课程
2、查看所教班级
3、查看班级中的学生
4、退出程序

逻辑图

course_system.py

#!/usr/bin/env python3
# author: Alnk(李成果)
import sys
import os
import json class Base: # 基础类
def __read_dic__(self, filename): # 读取json格式的文件
with open(filename, encoding='utf', mode='r') as f:
info_dic = json.load(f)
return info_dic def __wirte_dic__(self, filename, info_dic): # 写入json类型文件
with open(filename, encoding='utf', mode='w') as f:
json.dump(info_dic, f)
return True def __read_file__(self, filename): # 读取普通文件
file_list = []
with open(filename, encoding='utf', mode='r') as f:
for line in f:
file_list.append(line.strip())
return file_list def __write_file__(self, filename, info): # 写入普通文件
with open(filename, encoding='utf', mode='a') as f:
f.write('%s\n' % info)
return True class Parent(Base): # 父类
def show_courses(self): # 查看所有课程
courses_list = self.__read_file__('course_list')
print('\n所有课程:%s' % courses_list)
return courses_list def exit(self): # 退出
exit() class Student(Parent): # 学生类
option_lis = [('show_courses', '查看所有课程'),
('select_course', '选择课程'),
('check_selected_course', '查看已选课程'),
('exit', '退出'),
] def __init__(self, name):
self.name = name def select_course(self): # 选择课程
course_list = self.show_courses() # 查看所有课程
select_course = input('输入课程名称>>')
if select_course in course_list:
stu_dic = self.__read_dic__(self.name) # 读取学生个人详细信息
stu_dic["select_course"].append(select_course)
self.__wirte_dic__(self.name, stu_dic) # 写入学生个人信息
else:
print('课程不存在') def check_selected_course(self): # 查看已选课程
stu_dic = self.__read_dic__(self.name) # 读取学生个人信息
print('已选课程:', stu_dic["select_course"]) class Manage(Parent): # 管理员类
option_lis = [
('create_course', '创建课程'),
('create_stu', '创建学生'),
('show_courses', '查看所有课程'),
('show_students', '查看所有学生'),
('show_students_courses', '查看所有学生的选课情况'),
('create_teacher', '创建讲师'),
('create_class', '创建班级'),
('appoint_tearcher_class', '为讲师指定班级'),
('appoint_stu_class', '为学生指定班级'),
('exit', '退出'),
] def __init__(self, name):
self.name = name def create_course(self): # 创建课程
course_name = input('课程名称>>>').strip()
self.__write_file__('course_list', course_name) # 写入课程文件
print('\n%s课程创建成功\n' % course_name) def create_stu(self): # 创建学生
stu_name = input('学生账号>>>')
stu_pwd = input('密码>>>')
stu_info_dic = {'username': stu_name, 'passwd': stu_pwd, 'id': 'Student', 'select_course': [], 'class': []}
self.__wirte_dic__(stu_name, stu_info_dic) # 写入学生详细信息
self.__write_file__('students_list', stu_name) # 学生总列表
print('\n学生%s创建成功\n' % stu_name) def show_students(self): # 查看所有学生
students_list = self.__read_file__('students_list') # 读取学生总列表文件
print('\n所有的学生:%s' % students_list) def show_students_courses(self): # 查看所有学生的选课情况
stu_lis = self.__read_file__('students_list') # 读取学生总列表文件
for i in stu_lis:
stu_dic = self.__read_dic__(i) # 学生个人详细信息
print('%s 选课情况:%s' % (i, stu_dic['select_course'])) def create_teacher(self): # 创建讲师
t_name = input('讲师账号>>>')
t_pwd = input('密码>>>')
t_dic = {"username": t_name, "passwd": t_pwd, "id": "Teacher", "class": []}
self.__wirte_dic__(t_name, t_dic) # 写入老师详细信息
self.__write_file__('teacher_list', t_name) # 写入老师总文件
print('讲师 %s 创建成功' % t_name) def appoint_tearcher_class(self): # 为讲师指定班级
teacher_list = self.__read_file__('teacher_list') # 读取老师总文件
class_list = self.__read_file__('class_list') # 读取班级总文件
print('所有老师:%s' % teacher_list)
t_name = input('讲师名称>>>').strip()
print('所有班级:%s' % class_list)
c_name = input('班级名称>>>').strip()
if t_name in teacher_list and c_name in class_list:
teacher_dic = self.__read_dic__(t_name) # 读取老师个人信息
teacher_dic['class'].append(c_name)
self.__wirte_dic__(t_name, teacher_dic) # 写入老师个人信息
print('已为讲师 %s 指定班级 %s' % (t_name, c_name))
else:
print('讲师或班级不存在') def create_class(self): # 创建班级
class_name = input('创建班级名称:')
self.__write_file__('class_list', class_name) # 写入班级总文件
print('%s 班级创建成功' % class_name) def appoint_stu_class(self): # 为学生指定班级
stu_list = self.__read_file__('students_list') # 读取学生总列表文件
class_list = self.__read_file__('class_list') # 读取班级总文件
print('所有学生:%s' % stu_list)
stu_name = input('学生名称>>>')
print('所有班级:%s' % class_list)
class_name = input('班级名称>>>')
if stu_name in stu_list and class_name in class_list:
self.__write_file__(class_name, stu_name) # 写入班级文件
stu_dic = self.__read_dic__(stu_name) # 读取学生信息
stu_dic['class'].append(class_name)
self.__wirte_dic__(stu_name, stu_dic)
print('为学生 %s 指定班级 %s 成功' % (stu_name, class_name))
else:
print('班级或学生不存在') class Teacher(Parent): # 讲师类
option_lis = [('show_courses', '查看所有课程'),
('show_class', '查看所教班级'),
('show_class_students', '查看班级中的学生'),
('exit', '退出'),
] def __init__(self, name):
self.name = name def show_class(self): # 查看所教班级
tearcher_dic = self.__read_dic__(self.name)
print('所教班级%s' % tearcher_dic['class']) def show_class_students(self): # 查看班级中的学生
tearcher_dic = self.__read_dic__(self.name)
print('%s 班级中的学生:' % tearcher_dic['class'])
for i in tearcher_dic['class']:
stu_list = self.__read_file__(i)
print(stu_list) def login(): # 登录函数
name = input('username>>>:')
pwd = input('password>>>:')
if os.path.isfile(name):
with open(name, encoding='utf-8', mode='r') as f:
user_dic = json.load(f)
if user_dic['passwd'] == pwd:
return {'result': True, 'name': name, 'id': user_dic['id']}
else:
return {'result': False, 'name': name}
else:
return {'result': False, 'name': name} def main():
ret = login()
if ret['result']:
print('登录成功')
if hasattr(sys.modules[__name__], ret['id']):
cls = getattr(sys.modules[__name__], ret['id']) # 类
obj = cls(ret['name']) # 实例化
while 1:
print('\n')
for k, i in enumerate(cls.option_lis, 1):
print(k, i[1])
try:
choice = int(input(">>>:"))
except ValueError:
print("\n请输入编号")
continue
func_str = cls.option_lis[choice - 1][0]
if hasattr(obj, func_str):
getattr(obj, func_str)()
else:
print('登录失败') if __name__ == '__main__':
main()

admin

{"username": "admin", "passwd": "123", "id": "Manage"}

最新文章

  1. HTML基础
  2. 移动终端app测试点总结
  3. cursor:pointer
  4. JMeter2.13 连接 sql server
  5. 转载 GUID介绍
  6. 用于Lucene的各中文分词比较
  7. 门面(Facade)模式--医院,保安系统实例
  8. ASP.NET MVC项目里创建一个aspx视图
  9. gulp+browser-sync使用方法
  10. 深入认识XmlReader
  11. IntelliJ IDEA 中 Web项目 目录结构
  12. MyBatis进阶(四)
  13. yarn查询/cluster/nodes均返回localhost
  14. 转载:HBuilder常用快捷键
  15. 约瑟夫环(Joseph)的高级版(面向事件及“伪链表””)
  16. 自定义SpringBoot控制台输出的图案
  17. java List/ArrayList 解惑
  18. dcm4che,WADO相关
  19. Mysql文章笔记
  20. 浅谈React和VDom关系

热门文章

  1. 用Spingboot获得微信小程序的Code以及openid和sessionkey
  2. 巧用SpringBoot扩展点EnvironmentPostProcessor
  3. 『无为则无心』Python函数 — 27、Python函数的返回值
  4. tf-gpu报错:ImportError: libcublas.so.10.0: cannot open shared object file: No such file or directory
  5. Local dimming algorithm in matlab plus 1
  6. ARTS第五周
  7. 传统.NET 4.x应用容器化体验(1)
  8. java02动手动脑
  9. 使用python对工作簿每个sheet表进行数据可视化展示(本案例是从第2个sheet开始循环读取也就是索引为1的表)
  10. 【转载】Java学习笔记