python上下文操作linux

python上下文操作linux

上下文管理

什么是上下文管理,在编程过程中,通常用来表示代码执行过程中的前后操作,例如open函数,在操作文件之前,需要打开文件,然后再对文件进行读写操作,操作结束后,需要关闭文件。

上下文管理的作用场景:文件操作、网络连接与断开,数据库连接操作及断开等。

示例

我们在使用open函数对文件操作时,是这样实现的#获取文件对象fp = open('info','a+')#对文件的操作#操作接收后,关闭文件流fp.close()

上面的方法,虽然可以实现文件的读写操作,但是如果文件的操作过程中,发生了异常,会导致fp.close()不会执行。

修改

#获取文件对象try:fp = open('info','a+')#对文件的操作except:print('这里发生了异常')#操作接收后,关闭文件流finally:fp.close()

通过这种方式,添加异常处理,使用finally老保证不管是否发生异常,都执行关闭文件操作,以确保文件的正常关闭。

上述方法虽然能解决这个问题,但是实现过程中,需要做出对应的异常处理,比较麻烦。

所以我们可以使用with语法来实现,with实际上就是上下文的管理。

with open('info','a+') as fp:#文件操作

with时如何实现上下文管理的,如何编写一个自己的上下文管理呢

在python中,如果一个类,实现了__enter__()方法和__exit__()方法,那么这个类就可以是一个上下文管理器。

__enter__():用来表示上文管理,需要返回一个操作对象

__exit__():执行结束后的方法,不管过程中是否发生异常,这里都会执行,也是with中执行结束后的操作

实例

class File:    def __init__(self):        print('执行构造方法')    def __enter__(self):        print('进入方法')    def __exit__(self, exc_type, exc_val, exc_tb):        print('执行结束方法')with File() as f:    print('执行操作')

执行结果

执行构造方法进入方法执行操作执行结束方法

执行过程是先创建一个File类的对象,并命名为f,实例化时,调用了init方法,所以输出“执行构造方法”,然后再调用enter方法,输出“进入方法”。在执行with下的子句,即用户操作方法

通过上下文操作mysql数据库

# 封装的类是可以提供方法的,但是需要考虑异常处理问题# 还要考虑如何确保链接的关闭class Mysql(object):    def __init__(self,**kwargs):        self.conn = pymysql.connect(**kwargs)        self.cursor = self.conn.cursor()    def execsql(self,sql):        self.cursor.execute(sql)        return  self.cursor.fetchall()    def fetch(self,n=1):        return self.cursor.fetchmany(n)    def close(self):        self.cursor.close()        self.conn.close()class Mysql_with(object):    # 通过构造方法实现数据库连接的创建    def __init__(self,**kwargs):        self.conn = pymysql.connect(**kwargs)        # 获取游标对象        self.cursor = self.conn.cursor()    def __enter__(self):        # 返回一个游标对象        return self.cursor    def __exit__(self, exc_type, exc_val, exc_tb):        self.cursor.close()        self.conn.close()with Mysql_with(host='192.168.2.99',port=3306,user='root',passwd='',db='mysql') as mysql:    # mysql是什么,mysql接收的是__enter__方法返回的结果。所以mysql是cursor    mysql.execute('select user,host from user;')    print(mysql.fetchall())

上下文操作linux

class Linux:    def __init__(self,host='',user='',password='',port=22):        self.host = host        self.user = user        self.password = password        self.port = port        # 初始化ftp        self.ftp = ''        # 初始化ssh        self.ssh = ''class SSH_Linux(Linux):    def __enter__(self):        # self.__ssh()        return self    def command(self,comd):        # 调用ssh连接,创建连接        try:            self.__ssh()        except AuthenticationException:            return '登录错误'        except TimeoutError:            return '连接失败,请检查服务地址是否正确'        stdin,stdout,stderr = self.ssh.exec_command(comd)        # 处理命令的执行结果,并返回        return str(stdout.read(),encoding='utf-8')    def __ssh(self):        #创建ssh连接        self.ssh = paramiko.SSHClient()        try:            self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())            self.ssh.connect(hostname=self.host,username=self.user,password=self.password,port=self.port)        except AuthenticationException:            raise AuthenticationException        except TimeoutError:            raise TimeoutError    def __exit__(self, exc_type, exc_val, exc_tb):        self.ssh.close()class FTP_Linux(Linux):    def __enter__(self):        return self    def __ftp(self):        # 创建ftp连接        self.transport = paramiko.Transport((self.host,self.port))        try:            self.transport.connect(username=self.user,password=self.password)        except AuthenticationException:            raise AuthenticationException        self.ftp = paramiko.SFTPClient.from_transport(self.transport)    def get(self,source,dept):        try:            self.__ftp()        except AuthenticationException:            return '登录错误'        # 处理没有找到要下载的文件问题        try:            # 判断dest是否是一个文件            if os.path.isfile(dept):                self.ftp.get(source,dept)            elif os.path.isdir(dept):                # 读取到要下载的文件的文件名                file = os.path.basename(source)                # 将文件名和下载路径拼接                file_name = os.path.join(dept,file)                self.get(source,file_name)            elif not os.path.exists(dept):                self.ftp.get(source,dept)        except    FileNotFoundError:            return '要下载的目标文件不存在'    def put(self,source,dept):        try:            self.__ftp()        except AuthenticationException:            return '登录错误'        # 检查要上传的文件是否存在        if os.path.isfile(source):            self.ftp.put(source,dept)        else:            return '上传必须是已存在的文件'    def __exit__(self, exc_type, exc_val, exc_tb):        self.ftp.close()        self.transport.close()# ssh = Linux('192.168.2.16',user='root',password='123456')# with SSH_Linux('192.168.2.16',user='root',password='123456') as ssh:#     print(ssh.command('ls'))with FTP_Linux('192.168.2.16',user='root',password='123456') as ftp:    ftp.get('/home/test','.')

如果对于python访问linux系统不是很熟悉的话,可以参考下面的demo

linux ssh连接

# 需要先安装paramikoimport paramikossh = paramiko.SSHClient()ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())ssh.connect('192.168.2.16',username='root',password='123456')stoin,out,err = ssh.exec_command('ls')# stoin标准输入,执行时,不关心。# out:标准输出流。用来接收命令执行的结果的# err:标准错误,用来接收命令执行失败的错误信息# 标准输出流返回的是一个二进制对象,所以需要转成字符串对象,需要用utf8编码print(str(out.read(),encoding='utf-8'))ssh.close()

linux文件上传下载

#coding=utf-8__author__ = 'jia'import paramiko#Transportj接收一个socker对象,也就是ip地址和端口,因为只有一个参数,所以将两个参数# 以元组的形式传入transport = paramiko.Transport(('192.168.2.16',22))# 创建连接transport.connect(username='root',password='123456')# 创建ftp连接(通过socker创建ftp连接)ftp = paramiko.SFTPClient.from_transport(transport)# 上传文件ftp.put('test.html','/home/test.html')# 下载文件ftp.get('/etc/passwd','D:\\password')# 关闭ftp连接ftp.close()# 关闭socker连接transport.close()
免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部