python 学习第十一课 上下文管理 paramiko 堡垒机 mysql操作

Rlock Lock

这两种琐的主要区别是:RLock允许在同一线程中被多次acquire。而Lock却不允许这种情况。注意:如果使用RLock,那么acquire和release必须成对出现,即调用了n次acquire,必须调用n次的release才能真正释放所占用的琐

>>> help(threading.RLock)

RLock(*args, **kwargs)

Factory function that returns a new reentrant lock.

A reentrant lock must be released by the thread that acquired it. Once a

thread has acquired a reentrant lock, the same thread may acquire it again

without blocking; the thread must release it once for each time it has

acquired it.(reentrant 再进去的,凹角的)

import threading

lock = threading.Lock() #Lock对象

lock.acquire()

lock.acquire()  #产生了死琐。

lock.release()

lock.release()

import threading

rLock = threading.RLock()  #RLock对象

rLock.acquire()

rLock.acquire() #在同一线程内,程序不会堵塞。

rLock.release()

rLock.release()

上下文管理器(context manager)

with   contextlib   yield

with

使用with…as .. 来打开文件,最后不需要显示的执行文件close,它会自动关闭文件,with就是一个简单的上下文管理器,它通过两个魔方方法来决定:

__enter__(self)

定义了当使用with语句的时候,会话管理器在块被初始创建事要产生的行为。请注意,__enter__的返回值与with语句的目标或者as后的名字绑定。

__exit__(self, exception_type, exception_value, traceback)

定义了当一个代码块被执行或者终止后,会话管理器应该做什么。它可以被用来处理异常、执行清理工作或做一些代码块执行完毕之后的日常工作。如果代码块执行成功,exception_type,exception_value,和traceback将会为None。否则,你可以选择处理这个异常或者是直接交给用户处理。如果你想处理这个异常的话,请确保__exit__在所有语句结束之后返回True。如果你想让异常被会话管理器处理的话,那么就让其产生该异常。

__enter__和__exit__对于那些定义良好以及有普通的启动和清理行为的类是很有意义的。你也可以使用这些方法来创建一般的可以包装其它对象的会话管理器。

class hello(object):

def __init__(self, text):

self.text = text

print self.text

def __enter__(self):

self.text = "hello " + self.text    # add prefix

print self.text

return self                          # note: return an object

def __exit__(self,exc_type,exc_value,traceback):

self.text = self.text + " i love u"          # add suffix

with hello("world") as myhello:

pass

print(myhello.text)

输出结果:

world                #__init__的结果

hello world           #__enter__的结果

hello world I lov u       #__exit__的结果

当程序块中出现异常(exception),__exit__()的参数中exc_type, exc_value, traceback用于描述异常。我们可以根据这三个参数进行相应的处理。如果正常运行结束,这三个参数都是None。

contextlib

Python标准库包括了一个叫作 contextlib 的模块,其包含了一个上下文管理器contextmanager,它是为了加强with语句,提供上下文机制的模块,它是通过Generator实现的。通过定义类以及写__enter__和__exit__来进行上下文管理虽然不难,但是很繁琐。contextlib中的contextmanager作为装饰器来提供一种针对函数级别的上下文管理机制。

        from contextlib import contextmanager        @contextmanager       def hello(text):               text = ‘hello‘+ text               print text               yield              text = text+‘ i love u‘              print text

       with hello("world"):               print "world"

首先执行yield前的代码,然后调用with中间包含的代码,最后执行yield后面代码

PARAMIKO

paramiko模块基于SSH用于连接远程服务器并执行相关操作

sshclient

用于连接远程服务器并执行基本命令

import paramiko

# 创建SSH对象

ssh = paramiko.SSHClient()

# 允许连接不在know_hosts文件中的主机

ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# 连接服务器

ssh.connect(hostname=‘192.168.137.2‘, port=22, username=’han’, password=‘123‘)

# 执行命令

stdin, stdout, stderr = ssh.exec_command(‘df‘)

# 获取命令结果

result = stdout.read()

# 关闭连接

ssh.close()

sshclient 封装transport

import paramiko

transport = paramiko.Transport((‘hostname‘, 22))

transport.connect(username=‘wupeiqi‘, password=‘123‘)

ssh = paramiko.SSHClient()

ssh._transport = transport

stdin, stdout, stderr = ssh.exec_command(‘df‘)

print stdout.read()

transport.close()

基于公钥密钥连接:

import paramiko

private_key = paramiko.RSAKey.from_private_key_file(‘/home/auto/.ssh/id_rsa‘)

# 创建SSH对象

ssh = paramiko.SSHClient()

# 允许连接不在know_hosts文件中的主机

ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# 连接服务器

ssh.connect(hostname=‘xxx‘,port=22, username=‘wupeiqi‘,key=private_key)

# 执行命令

stdin, stdout, stderr = ssh.exec_command(‘df‘)

# 获取命令结果

result = stdout.read()

# 关闭连接

ssh.close()

SSHClient 基于私钥封装 Transport

import paramiko

private_key = paramiko.RSAKey.from_private_key_file(‘/home/auto/.ssh/id_rsa‘)

transport = paramiko.Transport((‘hostname‘, 22))

transport.connect(username=‘wupeiqi‘, pkey=private_key)

ssh = paramiko.SSHClient()

ssh._transport = transport

stdin, stdout, stderr = ssh.exec_command(‘df‘)

transport.close()

SFTPClient

import paramiko

transport = paramiko.Transport((‘hostname‘,22))

transport.connect(username=‘wupeiqi‘,password=‘123‘)

sftp = paramiko.SFTPClient.from_transport(transport)

# 将location.py 上传至服务器 /tmp/test.py

sftp.put(‘/tmp/location.py‘, ‘/tmp/test.py‘)

# 将remove_path 下载到本地 local_path

sftp.get(‘remove_path‘, ‘local_path‘)

transport.close()

基于公钥密钥上传下载

使用密码连接

import paramiko

private_key = paramiko.RSAKey.from_private_key_file(‘/home/auto/.ssh/id_rsa‘)

transport = paramiko.Transport((‘hostname‘, 22))

transport.connect(username=‘wupeiqi‘, pkey=private_key )

sftp = paramiko.SFTPClient.from_transport(transport)

# 将location.py 上传至服务器 /tmp/test.py

sftp.put(‘/tmp/location.py‘, ‘/tmp/test.py‘)

# 将remove_path 下载到本地 local_path

sftp.get(‘remove_path‘, ‘local_path‘)

transport.close()

堡垒机

堡垒机执行流程:

管理员为用户在服务器上创建账号(将公钥放置服务器,或者使用用户名密码)

用户登陆堡垒机,输入堡垒机用户名密码,显示当前用户管理的服务器列表

用户选择服务器,并自动登陆

执行操作并同时将用户操作记录

登录服务器代码

tran = paramiko.Transport((hostname, port,))

tran.start_client()

default_path = os.path.join(os.environ[‘HOME‘], ‘.ssh‘, ‘id_rsa‘)

key = paramiko.RSAKey.from_private_key_file(default_path)

tran.auth_publickey(‘wupeiqi‘, key)

# 打开一个通道

chan = tran.open_session()

# 获取一个终端

chan.get_pty()

# 激活器

chan.invoke_shell()

#########

# 利用sys.stdin,肆意妄为执行操作

# 用户在终端输入内容,并将内容发送至远程服务器

# 远程服务器执行命令,并将结果返回

# 用户终端显示内容

#########

chan.close()

tran.close()

中间代码块 1:普通模式,输入命令回车后将命令发给服务器

while True:

# 监视用户输入和服务器返回数据

# sys.stdin 处理用户输入

# chan 是之前创建的通道,用于接收服务器返回信息

readable, writeable, error = select.select([chan, sys.stdin, ],[],[],1)

if chan in readable:

try:

x = chan.recv(1024)

if len(x) == 0:

print ‘\r\n*** EOF\r\n‘,

break

sys.stdout.write(x)

sys.stdout.flush()

except socket.timeout:

pass

if sys.stdin in readable:

inp = sys.stdin.readline()

chan.sendall(inp)

中间代码块 2:每输入一个字符,都会发到服务器端sys.stdin.read(1)

# 获取原tty属性

oldtty = termios.tcgetattr(sys.stdin)

try:

# 为tty设置新属性

# 默认当前tty设备属性:

#   输入一行回车,执行

#   CTRL+C 进程退出,遇到特殊字符,特殊处理。

# 这是为原始模式,不认识所有特殊符号

# 放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到远程服务器

tty.setraw(sys.stdin.fileno())

chan.settimeout(0.0)

while True:

# 监视用户输入和远程服务器返回数据(socket)

# 阻塞,直到句柄可读

r, w, e = select.select([chan, sys.stdin], [], [], 1)

if chan in r:

try:

x = chan.recv(1024)

if len(x) == 0:

print ‘\r\n*** EOF\r\n‘,

break

sys.stdout.write(x)

sys.stdout.flush()

except socket.timeout:

pass

if sys.stdin in r:

x = sys.stdin.read(1)

if len(x) == 0:

break

chan.send(x)

finally:

# 重新设置终端属性

termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)

中间代码块 3:

def windows_shell(chan):

import threading

sys.stdout.write("Line-buffered terminal emulation. Press F6 or ^Z to send EOF.\r\n\r\n")

def writeall(sock):

while True:

data = sock.recv(256)

if not data:

sys.stdout.write(‘\r\n*** EOF ***\r\n\r\n‘)

sys.stdout.flush()

break

sys.stdout.write(data)

sys.stdout.flush()

writer = threading.Thread(target=writeall, args=(chan,))

writer.start()

try:

while True:

d = sys.stdin.read(1)

if not d:

break

chan.send(d)

except EOFError:

# user hit ^Z or F6

pass

注:密码验证 t.auth_password(username, pw)

python mysql api

插入数据

import MySQLdb

conn = MySQLdb.connect(host=‘127.0.0.1‘,user=‘root‘,passwd=‘1234‘,db=‘mydb‘)

cur = conn.cursor()

reCount = cur.execute(‘insert into UserInfo(Name,Address) values(%s,%s)‘,(‘alex‘,‘usa‘))

conn.commit()

cur.close()

conn.close()

print reCount

批量插入

li =[ (‘alex‘,‘usa‘), (‘sb‘,‘usa‘),  ]

reCount = cur.executemany(‘insert into UserInfo(Name,Address) values(%s,%s)‘,li)

取数据

reCount = cur.execute(‘select * from UserInfo‘)

print cur.fetchone()

print cur.fetchone()   #取一条

cur.scroll(-1,mode=‘relative‘)

print cur.fetchone()

print cur.fetchone()

cur.scroll(0,mode=‘absolute‘)

print cur.fetchmany(3)   #取多条

print cur.fetchone(5)

cur.close()

conn.close()

print reCount

nRet = cur.fetchall()    #全部取出

reCount 为影响的行数

int(cur.lastrowid)  返回这个游标最后一个记录的主键ID

int(conn.insert_id()) 返回这个连接的最后一个记录的主键ID

如果有多个游标,lastrowid不同,但conn.insert_id 相同,除非 conn也不同

时间: 2024-12-29 01:12:29

python 学习第十一课 上下文管理 paramiko 堡垒机 mysql操作的相关文章

【Python学习之旅】---上下文管理协议

# with obj as f:# '代码块'## 1.# with obj - --->触发obj.__enter__(), 拿到返回值## 2.as f - ---->f = 返回值.## 3.# with obj as f 等同于 f=obj.__enter__()## 4.# 执行代码块# 一:没有异常的情况下,整个代码块运行完毕后去触发__exit__, 它的三个参数都为None# 二:有异常的情况下,从异常出现的位置直接触发__exit__# a:如果__exit__的返回值为Tr

Python学习第十一课——装饰器

#装饰器:本质就是函数,为其他函数附加功能原则:1.不修改被修饰函数的源代码2.不修改被修饰函数的调用方式 装饰器=高阶函数+函数嵌套+闭包 #高阶函数 ''' 高阶函数定义: 1.函数接受的参数是一个函数名 2.函数的返回值是一个函数名 3.满足上述条件任意一个,都可称之为高阶函数 ''' # 函数接受的参数是一个函数名的情况下,要改变函数的调用方式 def foo(): time.sleep(2) print("憨憨你好") def test(func): print(func)

#paramiko 堡垒机

1 #paramiko 堡垒机 2 import paramiko 3 4 #创建SSH对象 5 ssh = paramiko.SSHCLient() 6 7 #允许连接不在know_hosta文件中的主机 8 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 9 10 #连接服务器 #主机名 #端口号 #账号 #密码 11 ssh.connect(hostname='c1.salt.com',port = 22,username

流畅的python第十五章上下文管理器和else块学习记录

with 语句和上下文管理器for.while 和 try 语句的 else 子句 with 语句会设置一个临时的上下文,交给上下文管理器对象控制,并且负责清理上下文.这么做能避免错误并减少样板代码,因此 API 更安全,而且更易于使用.除了自动关闭文件之外,with 块还有很多用途 else 子句不仅能在 if 语句中使用,还能在 for.while 和 try 语句中使用 for 仅当 for 循环运行完毕时(即 for 循环没有被 break 语句中止)才运行 else 块.while 仅

python学习第十课续 :线程池

线程分步走 t=threading.Thread(target=fun,args=()) t.start() 执行流程:         threading.Thread(target=fun,args=()) à           self.__target = target          self.__name = str(name or _newname())          self.__args = args         t.start  à           _star

Python全栈day28(上下文管理)

我们知道在操作文件对象的时候可以这么写 with open('a.txt',''r) as f: 代码 上述叫做上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明__enter__和__exit__方法 上下文管理协议.py class Open: def __init__(self,name): self.name = name def __enter__(self): print('执行enter') return self def __exit__(s

Python基础(30)——上下文管理,描述符,类装饰器,元类

上下文管理 with with open ('a.txt')  as f :       open(a.txt)就是实例化文件得到了一个对象,然后把对象赋值个f ,with 一个f的对象 ,后面不需要再写关闭,是因为类中间定义了一个协议,__enter__   __exit__来实现 原文地址:https://www.cnblogs.com/dayouge/p/11218698.html

哗啦啦Python之路 - sqlalchemy/paramiko/堡垒机

I. SQLalchemy联表操作 1. 一对多 class Group(Base): # 一对多的表,组中可能包含多个用户 __tablename__ = 'group' nid = Column(Integer, primary_key=True, autoincrement=True) caption = Column(String(32)) class User(Base): __tablename__ = 'user' uid = Column(Integer, primary_key

Python学习(九)IO 编程 —— 文件夹及文件操作

Python 文件夹及文件操作 我们经常会与文件和目录打交道,对于这些操作,python可以使用 os 及 shutill 模块,其中包含了很多操作文件和目录的函数.这边,仅介绍通常会用到的方法. os 可以操作简单的文件夹及文件操作,引入用  import os,可用  help(os)  或是  dir(os)  查看其用法.注意有些函数在os模块中,有的是在os.path模块中. shutil 模块提供了大量的文件的高级操作.特别针对文件拷贝和删除,主要功能为目录和文件操作以及压缩操作.须