如何用-Python-做一个在云端运行的-学生管理系统-

Python作为一个编程语言,在近几年还是很火的,毕竟代码可以实现的功能还很多,也很厉害。
学生管理系统对于当前的学生来说都是学习必备,刷题必备,基本学一个语言就要做一个学生管理系统,方法无疑就是在本地创建一个txt文件然后写入以及读取其内容。然而缺点也随即出现,无论什么语言,都会极大地消磨本地内存,如果建立的学生文件过多或者文件里行数过多,也会极大占用内存,这无疑是很明显的缺点。

Paramiko 作为Python的一个第三方库,其主要包括两个核心组件: SSHClientSFTPClient
1.SSHClient 的作用类似于Linux的ssh命令,是对SSH会话的封装,该类封装了传输(Transport),通道(Channel)及 SFTPClient 建立的方法(open_sftp),通常用于 执行远程命令
2.SFTPClient的作用类似与 Linuxsftp命令 ,是对SFTP客户端的封装,用以实现 远程文件操作 ,如 文件上传、下载、修改文件权限 等操作。
(解释来自这个网站)
其不仅支持这两个方法,还能进行远程登录连接Linux主机,对于我这个标题,无疑就是使用这个库连接服务器或者虚拟机进行操作。

注:所有方法以及原理在下面的代码中已经全部注释,主要有几点需要注意:
-1.一定要在服务器内建好绝对路径!
-2.一定注意方法中是否存在sftp或者sftp_client的变量,不然会导致提前关闭全局变量sftp或者sftp_client!导致无法循环使用!
-3.无论 -添加/修改- 还是 -查找- 或是 -删除-,一定要检查服务器路径是否绝对,是否正确,如果不正确,很有可能导致服务器错乱或者报错!
-4.如果使用虚拟机,打开/etc/sysconfig/network-scripts/ifcfg-eth0,获取到ip地址,reboot后再使用代码连接
-5.如果使用本地Linux主机,找对自己的IP地址再进行代码连接
-6.如果使用远程Linux主机,如果不用于其他用途,请一定不要使用公网IP
-7.SFTPClient的端口号是22
-8.一定加入login方法!!!

注意事项已经标注,请检查完毕再试运行代码!

第一步:部署 SSHClientSFTPClient
(注:这里会用到 Paramiko 里的 Transport() 方法进行链接)

#导入相应的包
import paramiko
import os
import sys

#设置登录服务器参数
hostname = "(ip.ip.ip.ip)"
#因为使用的文件传输协议,所以使用22端口
port = 22
username = "name"
password = "password"
'''
paramiko的参数设置是hostname(服务器或虚拟机ip地址),port(端口号,传输文件一般使用22端口),username password(登录服务器的用户名和密码)
'''

#初始化ssh
'''
初始化SSHClient里,先初始化核心方法SSHClient(),调用里面的connect()将刚刚的参数传进来,进行连接服务器
'''
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname, port, username, password, compress=True)

#初始化transport
'''
在transport里,传入ip端口以及用户名密码进行connect连接
'''
transport = paramiko.Transport((hostname, 22))
transport.connect(username = username, password = password)

#初始化sftp(即调用SFTPClient)
sftp = paramiko.SFTPClient.from_transport(transport)
sftp_client = client.open_sftp()
'''
这里并没有使用两种方法而多此一举,各有各的用法
'''

第二步:分明函数作用(并不使用class定义类)

def chooce():
	pass

def remove_student():
	pass

def find_student():
	pass

def add_student():
	pass

def login():
	pass

if __name__ == '__main__':
	login()

'''
这里分开了几个方法,选择界面、删除学生、查找学生、添加学生、登录窗口
	-设置登录窗口主要是因为毕竟是因为这个库可以操作服务器,可以用几个方法进行删除或者上传文件的操作,看得见日志可以ban IP但是还是小心为好。
'''

第三步:部署login()

def login():
	try:
		print('***连接成功***\n')

		#建立读取用户名和密码的列表,将服务器内文件的字符遍历进列表
    	name = []
    	psw = []
    
    	#因为已经有了sftp_client的全局变量(调用方法),这里可以注释掉
    	#sftp_client = client.open_sftp()
    
    	#读取服务器内的文件
    	name_file = sftp_client.open("/student/login/name.txt")
    	psw_file = sftp_client.open("/student/login/password.txt")
    	
    	try:
    		#如果可以读取到(只要连接上,这里一般是都可以读取到的,except存不存在主要是看主机可不可以连接成功)
    		#使用for循环读取登录程序的用户名和密码,将其遍历进列表
        	for p in psw_file:
            	psw.append(p)
        	for n in name_file:
            	name.append(n)
    	finally:
    		#finally里可以是pass,不需要关闭文件流,如果操作存在强迫症,完全可以添加文件流的关闭
        	#name_file.close()
        	#psw_file.close()
        	pass
        
        #输入登录程序的用户名和密码
    	user = input("用户名:")
    	user_psw = input("密码:")
    	
    	#进行判定是否登录成功
    	if(len(user) == 0 or len(user_psw) == 0):
        	print("请不要输入为空!")
        	login()
    	elif(user == name[0] and user_psw == psw[0]):
        	print("登陆成功!\n")
        	chooce()
    	elif(user != name[0]):
        	print("用户名错误!")
        	login()
    	elif(user_psw != psw[0]):
        	print("密码错误!")
        	login()
	except:
		print(***连接失败***)

第三步:部署chooce()

def chooce():
	#这里比较简单,不做过多介绍
    print('***请选择您的操作***\n')
    print('**1.添加/修改 学生**')
    print('**2.查找学生**')
    print('**3.删除学生**')
    print('**4.退出程序**')
    print('\n***请选择您的操作***\n')
    
    answer = int(input('您的选择:'))
    
    if(answer == 1):
        add_student()
    elif(answer == 2):
        find_student()
    elif(answer == 3):
        remove_student()
    elif(answer == 4):
        print('\n***感谢您的使用(By WangPeiXi)')
        sys.exit(0)
        sftp.close()
    else:
        print('请输入正确的选择!')
        chooce()

第四步:部署add_student()

def add_student():
    print("\n---添加/修改 学生---\n")
    print("---退回请输入‘exit’---\n")
    student_name = input("输入学生姓名:")

	#这里一样因为已经有了sftp_client的全局变量(调用方法),这里可以注释掉
   	#sftp_client = client.open_sftp()
    
    if(len(student_name) == 0):
        print("请不要输入为空!")
        add_student()
    elif(student_name == 'exit'):
        print('即将返回!\n')
        chooce()
    else:
    	#这里运用到了os库,原因是因为我没试过直接读取服务器里的文件行,原理是在本地生成文件然后上传指定目录再删除本地文件
    	#local_file(本地文件)//remote_file(服务器绝对目录!!!一定是绝对目录以及文件名!!!)
        local_file = student_name + '.txt'
        remote_path = '/student/students/' + student_name + '.txt'
        
        with open(local_file,'a') as stu:
            #这里在本地写入文件内容,如果可以还可以加入其他内容
            stu_class = input("输入班级:")
            stu_age = input("输入年龄:")
            stu_home = input("输入籍贯:")
            stu_id = input("输入学号:")
                    
            stu.write(student_name + '\n')
            stu.write(stu_class + '\n')
            stu.write(stu_age + '\n')
            stu.write(stu_home + '\n')
            stu.write(stu_id)
                    
            #一定不要忘记关闭文件流!不然会报错正在使用改文件!
            stu.close()
            
                
        	#读取的时候会将换符行(\n)一块读取

        try:
        	#如果成功的话,执行SFTPClient里的put函数,将本地文件上传到服务器的绝对目录
        	#这里有一个小小的bug,现在还没有解决,就是如果服务器内存在文件,如果两次上传了一个一模一样的文件名,那么第一个文件(也就是第一次上传的文件)会被第二个文件覆盖,无论文件名还是内容
            sftp.put(local_file,remote_path)
        except Exception as e:
        	#这里运用到sys.exit(1)主要是以一个失败的方式关闭
            print("上传失败")
            sys.exit(1)
        finally:
        	#可以注释掉这一句,如果add_student()里没有局部变量sftp则一定要注释掉这一句!
            #sftp.close()
            pass
               
        #删除本地文件
        os.remove(local_file)
                
        print("添加完成!\n")
        add_student()

第四步:部署find_student()

def find_student():
    print('\n---查找学生---\n')
    print("---退回请输入‘exit’---\n")
    student_name = input('输入学生姓名:')

	#这里一样因为已经有了sftp_client的全局变量(调用方法),这里可以注释掉
   	#sftp_client = client.open_sftp()    

    #这里一样运用到了os库,原因是因为我没试过直接读取服务器里的文件行,原理是将服务器的文件里下载到本地然后逐行读取再删除本地文件
   	#local_file(本地文件)//remote_file(服务器绝对目录!!!一定是绝对目录以及文件名!!!)
   	#如果没什么问题,可以将local_file和remote_file放在方法之前作为全局变量
    local_file = student_name + '.txt'
    remote_path = '/student/students/' + student_name + '.txt'
    
    if(len(student_name) == 0):
        print('请不要输入为空!')
        find_student()
    elif(student_name == 'exit'):
        print('即将返回!\n')
        chooce()
    try:
    	#如果成功则执行sftp里的get方法,将服务器文件下载到本地
        sftp.get(remote_path,local_file)
        #这里注意encoding的编码
        with open(local_file,'r',encoding='gbk') as fstu:
            
			#读取文件每行
            stu = fstu.readlines()
            
            print('\n***已经找到该学生***\n')
            
            print('姓名:' + stu[0])
            print('班级:' + stu[1])
            print('年龄:' + stu[2])
            print('籍贯:' + stu[3])
            print('学号:' + stu[4])
            
            #一定关闭文件流!不然无法删除本地文件!
            fstu.close()
             
    except:
        print('\n---未找到该学生---\n')
        
    finally:
    	#这里也一样可以注释掉这一句,如果find_student()里没有局部变量sftp则一定要注释掉这一句!
        #sftp.close()
        #stu.close()
        pass
    
    #最后删除本地文件
    os.remove(local_file)
    
    find_student()

第五步:部署remove_student()

def remove_student():
    print("\n---删除学生---\n")
    print("---退回请输入‘exit’---\n")
    student_name = input("输入学生姓名:")
    
	#这里运用的方法和之前不一样,是执行transport里的stdin方法,在控制台执行一个“sudo -i rm -f”语句进行删除。

    if(len(student_name) == 0):
        print('请不要输入为空!')
        remove_student()
    elif(student_name == 'exit'):
        print('即将返回!\n')
        chooce()
    else:
    	#这里也必须是绝对路径,如果出错,那么可能删除其他文件!
        remote_path = '/student/students/' + student_name + '.txt'
        
        try:
        	#如果成功执行命令
            stdin,stdout,stderr=client.exec_command('sudo -i rm -f ' + remote_path,get_pty=True)
            stdin.write("test\n")
        except:
        	#连接到文件之后失败的原因只有文件不存在,换个方式理解也就是 -该学生不存在-
            print('---该学生不存在---\n')
            remove_student()
        finally:
        	#这里注释以及不注释都没什么区别
            #stdin.close()
            print('删除成功!\n')
            
    remove_student()

第六步:添加一个程序入口

if __name__ == '__mian__':
	login()

最后我把文件模板上传一份,你们可以下载,提取码是gatz。如果有什么建议或者bug可以及时分享一下,哈哈哈一起学习嘛!

你可能感兴趣的:(python,服务器)