Python模块使用技巧集合——SSH-paramiko模块,configparser模块,StringIO和BytesIO模块,collections模块

paramiko

用于帮助开发者通过代码远程连接服务器,并对服务器进行操作。

# pip3 install paramiko 

远程执行命令

import paramiko

# 创建SSH对象
ssh = paramiko.SSHClient()

# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# 连接服务器
ssh.connect(hostname='192.168.16.85', port=22, username='root', password='123456')

# 执行命令
stdin, stdout, stderr = ssh.exec_command('df')
# 获取命令结果
result = stdout.read()
# 关闭连接
ssh.close()

print(result.decode('utf-8'))

上传下载文件

import paramiko

transport = paramiko.Transport(('192.168.16.85', 22))
transport.connect(username='root', password='123456')
sftp = paramiko.SFTPClient.from_transport(transport)


# 将location.py 上传至服务器 /tmp/test.py
# sftp.put('123.txt', '/data/123.txt')
sftp.get('/data/123.txt', '123.txt')

transport.close()

通过公钥私钥远程执行命令

import paramiko

private_key = paramiko.RSAKey.from_private_key_file(r'C:/Users/Administrator/.ssh/id_rsa')

# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='192.168.16.85', port=22, username='root', pkey=private_key)

# 执行命令
stdin, stdout, stderr = ssh.exec_command('df')
# 获取命令结果
result = stdout.read()

# 关闭连接
ssh.close()

print(result)

通过公钥私钥远程上传下载文件

import paramiko

private_key = paramiko.RSAKey.from_private_key_file(r'C:/Users/Administrator/.ssh/id_rsa')

transport = paramiko.Transport(('192.168.16.85', 22))
transport.connect(username='root', pkey=private_key)

sftp = paramiko.SFTPClient.from_transport(transport)
# 将location.py 上传至服务器 /tmp/test.py
# sftp.put('/tmp/123.py', '/tmp/123.py')

# 将remove_path 下载到本地 local_path
# sftp.get('123.py', '123.py')

transport.close()

通过私钥字符串远程连接服务器

key = """-----BEGIN RSA PRIVATE KEY-----

-----END RSA PRIVATE KEY-----"""


import paramiko
from io import StringIO

private_key = paramiko.RSAKey(file_obj=StringIO(key))

# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='192.168.16.85', port=22, username='root', pkey=private_key)

# 执行命令
stdin, stdout, stderr = ssh.exec_command('df')
# 获取命令结果
result = stdout.read()

# 关闭连接
ssh.close()

print(result)

生成公钥私钥并上传

# 1 生成公钥和私钥s
sh-keygen.exe -m pem

# 2 在当前用户家目录会生成: .ssh/id_rsa.pub    .ssh/id_rsa

# 3 把公钥放到服务器
ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.16.85 

# 4 以后再连接服务器时,不需要在输入密码
ssh root@192.168.16.85

configparser

configparser用于处理特定格式的文件,其本质上是利用open来操作文件。

configparser.ConfigParser

#  注释1
;  注释2
 
[section1]  # 节点
k1 = v1     # 
k2:v2       # 
 
[section2]  # 节点
k1 = v1     # 
  1. 获取所有节点

    import configparser
    config = configparser.ConfigParser()
    # 读取文件
    config.read('xxx.ini', encoding='utf-8')
    # 获取sections:list
    sections = config.sections()
    for section in sections:
    	# section:str
    	print(section)
    
  2. 获取指定节点下所有的键值对

    import configparser
    config = configparser.ConfigParser()
    config.read('xxx.ini', encoding='utf-8')
    # 获取items:list
    items = config.items('section1')
    for item in items:
    	# item:tuple (key,value)
    	print(item)
    
  3. 获取指定节点下所有的建

    import configparser
     
    config = configparser.ConfigParser()
    config.read('xxx.ini', encoding='utf-8')
    # 获取keys:list
    keys = config.options('section1')
    for key in keys:
    	# key:str
    	print(key)
    
  4. 获取指定节点下指定key的值

    import configparser
     
    config = configparser.ConfigParser()
    config.read('xxx.ini', encoding='utf-8')
     
    # v:str
    v = config.get('section1', 'k1')
    
    # v:int
    v = config.getint('section1', 'k1')
    
    # v:float
    v = config.getfloat('section1', 'k1')
    
    # v:bool
    v = config.getboolean('section1', 'k1')
    
  5. 检查、删除、添加节点

    import configparser
     
    config = configparser.ConfigParser()
    config.read('xxx.ini', encoding='utf-8')
     
     
    # 检查
    # has_sec:bool
    has_sec = config.has_section('section1')
     
    # 添加节点
    config.add_section("section1")
    # 写入
    config.write(open('xxx.ini', 'w'))
     
    # 删除节点
    config.remove_section("section1")
    # 写入
    config.write(open('xxx.ini', 'w'))
    
  6. 检查、删除、设置指定组内的键值对

    import configparser
     
    config = configparser.ConfigParser()
    config.read('xxx.ini', encoding='utf-8')
     
    # 检查
    # has_opt:bool
    has_opt = config.has_option('section1', 'k1')
    print(has_opt)
     
    # 删除
    config.remove_option('section1', 'k1')
    config.write(open('xxx.ini', 'w'))
     
    # 设置
    config.set('section1', 'k10', "123")
    config.write(open('xxx.ini', 'w'))
    

其他写法

>>> import configparser
>>> config = configparser.ConfigParser()
>>> config['DEFAULT'] = {'ServerAliveInterval': '45',
...                      'Compression': 'yes',
...                      'CompressionLevel': '9'}
>>> config['bitbucket.org'] = {}
>>> config['bitbucket.org']['User'] = 'hg'
>>> config['topsecret.server.com'] = {}
>>> topsecret = config['topsecret.server.com']
>>> topsecret['Port'] = '50022'     # mutates the parser
>>> topsecret['ForwardX11'] = 'no'  # same here
>>> config['DEFAULT']['ForwardX11'] = 'yes'
>>> with open('example.ini', 'w') as configfile:
...   config.write(configfile)

编码错误

如果出现编码错误,将encoding='gbk’即可。

StringIO&BytesIO

StringIO

数据读写不一定是文件,也可以在内存中读写。

StringIO顾名思义就是在内存中读写str。

  1. 把str写入StringIO
from io import StringIO
f = StringIO()
f.write('hello') # 5
f.write(' ') # 1
f.write('world!') # 6
print(f.getvalue()) # hello world!
  1. 读取StringIO
from io import StringIO
f = StringIO('Hello!\nHi!\nGoodbye!')
while True:
	s = f.readline()
	if s == '':
		break
	print(s.strip())

BytesIO

BytesIO实现了在内存中读写bytes

from io import BytesIO
f = BytesIO()
f.write('中文'.encode('utf-8')) # 6
print(f.getvalue()) # b'\xe4\xb8\xad\xe6\x96\x87'

和StringIO类似,可以用一个bytes初始化BytesIO

>>> from io import StringIO
>>> f = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')
>>> f.read() # b'\xe4\xb8\xad\xe6\x96\x87'

文件B模式

f.flush() 可以将内存的数据立即写入硬盘

# 指针移动都是以字节为单位的,但t模式下的read(n)是n个字符
f.seek(n,模式) 
n:移动字节数
模式: 0从头开始,1当前,2末尾,只有在b模式下才可以用1,2,否则只能0.

f.tell()获取当前指针的位置,可以用offset+=len(line)代替

collections模块

这个模块实现了特定目标的容器。

Counter

Counter是一个dict子类,主要是用来对频率进行计数。

# 统计字符出现的次数
>>> import collections
>>> collections.Counter('hello world')
Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1})
# 统计单词数
>>> collections.Counter('hello world hello world hello nihao'.split())
Counter({'hello': 3, 'world': 2, 'nihao': 1})

常用方法

  • elements():返回一个迭代器,每个元素重复计算的个数,如果一个元素的计数小于1,就会被忽略。
  • most_common([n]):返回一个列表,提供n个访问频率最高的元素和计数
  • subtract([iterable-or-mapping]):从迭代对象中减去元素,输入输出可以是0或者负数
  • update([iterable-or-mapping]):从迭代对象计数元素或者从另一个 映射对象 (或计数器) 添加。
>>> c = collections.Counter('hello world hello world hello nihao'.split())
>>> c
Counter({'hello': 3, 'world': 2, 'nihao': 1})
# 获取指定对象的访问次数,也可以使用get()方法
>>> c['hello']
3
>>> c = collections.Counter('hello world hello world hello nihao'.split())
# 查看元素
>>> list(c.elements())
['hello', 'hello', 'hello', 'world', 'world', 'nihao']
# 追加对象,或者使用c.update(d)
>>> c = collections.Counter('hello world hello world hello nihao'.split())
>>> d = collections.Counter('hello world'.split())
>>> c
Counter({'hello': 3, 'world': 2, 'nihao': 1})
>>> d
Counter({'hello': 1, 'world': 1})
>>> c + d
Counter({'hello': 4, 'world': 3, 'nihao': 1})
# 减少对象,或者使用c.subtract(d)
>>> c - d
Counter({'hello': 2, 'world': 1, 'nihao': 1})
# 清除
>>> c.clear()
>>> c
Counter()

defaultdict

参数应该是一个工厂函数,当没有参数调用时返回默认值。如果没有传递任何内容,则默认为None。

>>> d = collections.defaultdict(str)
>>> d
defaultdict(<class 'str'>, {})
>>> d['hello']
''
>>> d
defaultdict(<class 'str'>, {'hello': ''})
>>> from collections import defaultdict
>>> fruit = defaultdict(int)
>>> fruit['apple'] += 2 
>>> fruit
defaultdict(<class 'int'>, {'apple': 2})
>>> fruit
defaultdict(<class 'int'>, {'apple': 2})
>>> fruit['banana']  # 没有对象时,返回0
0
>>> fruit
defaultdict(<class 'int'>, {'apple': 2, 'banana': 0})
>>> s = [('NC', 'Raleigh'), ('VA', 'Richmond'), ('WA', 'Seattle'), ('NC', 'Asheville')]
>>> d = collections.defaultdict(list)
>>> for k,v in s:
...      d[k].append(v)
... 
>>> d
defaultdict(<class 'list'>, {'NC': ['Raleigh', 'Asheville'], 'VA': ['Richmond'], 'WA': ['Seattle']})

OrderedDict

顺序字典

>>> from collections import OrderedDict
>>> o = OrderedDict()
>>> o['key1'] = 'value1'
>>> o['key2'] = 'value2'
>>> o['key3'] = 'value3'
>>> o
OrderedDict([('key1', 'value1'), ('key2', 'value2'), ('key3', 'value3')])

namedtuple

>>> from collections import namedtuple
>>> Person = namedtuple('Person', ['age', 'height', 'name'])
>>> Human = namedtuple('Human', 'age, height, name')
>>> Human2 = namedtuple('Human2', 'age height name')
>>> tom = Person(30,178,'Tom')
>>> jack = Human(20,179,'Jack')
>>> tom
Person(age=30, height=178, name='Tom')
>>> jack
Human(age=20, height=179, name='Jack')
>>> tom.age #直接通过  实例名+.+属性 来调用
30
>>> jack.name
'Jack'

deque

collections.deque返回一个新的双向队列对象
collections.deque队列支持线程安全,对于从两端添加(append)或者弹出(pop),复杂度O(1)。

如果 maxlen 没有指定或者是 None ,deques 可以增长到任意长度。否则,deque就限定到指定最大长度。一旦限定长度的deque满了,当新项加入时,同样数量的项就从另一端弹出。

常用方法

  • append(x):添加x到右端
  • appendleft(x):添加x到左端
  • clear():清除所有元素,长度变为0
  • copy():创建一份浅拷贝
  • count(x):计算队列中个数等于x的元素
  • extend(iterable):在队列右侧添加iterable中的元素
  • extendleft(iterable):在队列左侧添加iterable中的元素,注:在左侧添加时,iterable参数的顺序将会反过来添加
  • index(x[,start[,stop]]):返回第 x 个元素(从 start 开始计算,在 stop 之前)。返回第一个匹配,如果没找到的话,raise ValueError 。
  • insert(i,x):在位置 i 插入 x 。注:如果插入会导致一个限长deque超出长度 - maxlen 的话,就raise一个 IndexError 。
  • pop():移除最右侧的元素
  • popleft():移除最左侧的元素
  • remove(value):移去找到的第一个 value。没有raiseValueError。
  • reverse():将deque逆序排列,返回 None 。
  • maxlen:队列的最大长度,没有限定则为None。
>>> from collections import deque
>>> d = deque(maxlen=10)
>>> d
deque([], maxlen=10)
>>> d.extend('python')
>>> [i.upper() for i in d]
['P', 'Y', 'T', 'H', 'O', 'N']
>>> d.append('e')
>>> d.appendleft('f')
>>> d
deque(['f', 'p', 'y', 't', 'h', 'o', 'n', 'e'], maxlen=10)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Generalzy

文章对您有帮助,倍感荣幸

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值