目录
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 # 值
-
获取所有节点
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) -
获取指定节点下所有的键值对
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) -
获取指定节点下所有的建
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) -
获取指定节点下指定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') -
检查、删除、添加节点
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')) -
检查、删除、设置指定组内的键值对
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。
- 把str写入StringIO
from io import StringIO
f = StringIO()
f.write('hello') # 5
f.write(' ') # 1
f.write('world!') # 6
print(f.getvalue()) # hello world!
- 读取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)
1819

被折叠的 条评论
为什么被折叠?



