Python paramiko 模块浅谈与SSH主要功能模拟解析


Posted in Python onFebruary 29, 2020

疫情还没结束,小编只能宅在家里,哪哪也去不了,今天突发奇想给大家分享一篇教程关于Python paramiko 模块浅谈与SSH主要功能模拟解析。

大家都知道,通过SSH服务可以远程连接到Linux服务器,查看上面的日志状态,批量配置远程服务器,文件上传,文件下载等,Python的paramiko模块同样实现了这一功能。

首先我们需要安装这一模块,pycharm环境中如下操作

一,安装paramiko模块

PyCharm→Preferences→Project:项目名→Project Interpreter

Python paramiko 模块浅谈与SSH主要功能模拟解析

点击箭头所指加号,在搜索框输入选中,并安装

Python paramiko 模块浅谈与SSH主要功能模拟解析

完成后会在Project Interpreter中显示,如上上图

二, 基于用户名和密码的 sshclient 方式登录

import paramiko
# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='192.168.199.146', port=22, username='fishman', password='9')
# 执行命令
stdin, stdout, stderr = ssh.exec_command('df')
# 获取命令结果
res,err = stdout.read(),stderr.read()
result = res if res else err
print(result.decode())
# 关闭连接
ssh.close()

解析:首先导入模块,然后创建一个SSH对象,然后通过命令连接远程机器,默认端口是22,这里我连接的是192.168.199.146的机器,密码为9,然后执行df命令,获取返回的结果如下

Python paramiko 模块浅谈与SSH主要功能模拟解析

我们可以比较一下通过SSH得到的结果

Python paramiko 模块浅谈与SSH主要功能模拟解析

三,基于用户名和密码的 transport 方式登录

基于SSHClient是传统的连接服务器、执行命令、关闭的一个操作,有时候需要登录上服务器执行多个操作,比如执行命令、上传/下载文件,上面方法则无法实现,可以通过如下方式来操作

#SSHClient 封装 Transport
import paramiko
# 实例化一个transport对象
transport = paramiko.Transport(('192.168.199.146', 22))
# 建立连接
transport.connect(username='fishman', password='9')
# 将sshclient的对象的transport指定为以上的transport
ssh = paramiko.SSHClient()
ssh._transport = transport
# 执行命令,和传统方法一样
stdin, stdout, stderr = ssh.exec_command('df')
print (stdout.read().decode())
# 关闭连接
transport.close()

四,基于公钥密钥连接

4.1 SSH配置免密登陆

我们知道通过配置公钥密钥,可以实现SSH的免密登陆,比如现在连接fishman机器会提示我们输入密码,然后才能登陆

Python paramiko 模块浅谈与SSH主要功能模拟解析

通过SSH原理与运用中介绍,我们知道,要实现免密公钥登陆,需要将我们自己机器的公钥存储在要登陆的远程主机上。登录的时候,远程主机会向用户发送一段随机字符串,用户用自己的私钥加密后,再发回来。远程主机用事先储存的公钥进行解密,如果成功,就证明用户是可信的,直接允许登录shell,不再要求密码。

首先我们生成自己的公钥通过命令 ssh-keygen,这里会提示这个公钥保存的文件路径,默认即可然后回车,这里由于我本地已经有生成的公钥,所以提示是否要覆盖,我这里就不重写了,如果本地没有生成过继续回车,提示要不要对私钥设置口令(passphrase),如果担心私钥的安全,这里可以设置一个。默认也可以直接回车

Python paramiko 模块浅谈与SSH主要功能模拟解析

得到公钥后一种方法是通过命令将公钥直接传到远程机器ssh-copy-id user@host,如我们登陆的机器:

ssh-copy-id fishman@192.168.199.146

另一种方法是进入公钥文件去复制,进入.ssh/id_rsa.pub通过more或者cat复制公钥

~ more .ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCyQ2GtkbKcFAP/kX/+65e91Q8EJ+twpyqjEBzlVmZ2mxy8Zw7b/AfeV60ehloCq7p521IGJaXWbr3bky7Jljc6x7cAZsRW7mZRPFelPYa5iJ4lIshU3RwhbTYW6RyrG+InF3ognJ7bggpPmJbWFxqqpZwdkEilpnv0+8b17frSbF1xaQQh57vDjG78xr0pys2MBzylqrs1RNiTcRz86zJT7SbujYY/bpiUB78w46CmRlwzHOk8Zg0hcegqSMHjboQyhkSX0xcFv2ZLHm5Gpfba3863M+62Q1r2U+QW5Ki1f3nsGwHWQIRuHNWldUzWKYRPsKJHVvwFwkYDG3sZZMWR ljf@meijiabaodeiMac.lan ~ cat .ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCyQ2GtkbKcFAP/kX/+65e91Q8EJ+twpyqjEBzlVmZ2mxy8Zw7b/AfeV60ehloCq7p521IGJaXWbr3bky7Jljc6x7cAZsRW7mZRPFelPYa5iJ4lIshU3RwhbTYW6RyrG+InF3ognJ7bggpPmJbWFxqqpZwdkEilpnv0+8b17frSbF1xaQQh57vDjG78xr0pys2MBzylqrs1RNiTcRz86zJT7SbujYY/bpiUB78w46CmRlwzHOk8Zg0hcegqSMHjboQyhkSX0xcFv2ZLHm5Gpfba3863M+62Q1r2U+QW5Ki1f3nsGwHWQIRuHNWldUzWKYRPsKJHVvwFwkYDG3sZZMWR ljf@meijiabaodeiMac.lan ~

复制后,我们登陆远程机器,在目录下.ssh文件夹中发现有以下文件,其中id_ras id_ras.pub保存该机器的公钥私钥,

know_hosts:ssh会把你每个你访问过计算机的公钥(public key)都记录在~/.ssh/known_hosts。当下次访问相同计算机时,OpenSSH会核对公钥。如果公钥不同,OpenSSH会发出警告, 避免你受到DNS Hijack之类的攻击。

我们需要将刚才复制的我的公钥保存到authorized_keys文件中

Python paramiko 模块浅谈与SSH主要功能模拟解析

Python paramiko 模块浅谈与SSH主要功能模拟解析

通过vi打开编辑然后粘贴退出保存

Python paramiko 模块浅谈与SSH主要功能模拟解析

此时,我们退出登陆,然后重新登陆,发现就不需要输入登陆密码了,可以实现免密登陆,美滋滋。

Python paramiko 模块浅谈与SSH主要功能模拟解析

另外我们要注意,.ssh目录的权限为700,其下文件authorized_keys和私钥的权限为600。否则会因为权限问题导致无法免密码登录

Python paramiko 模块浅谈与SSH主要功能模拟解析

另外,将公钥拷贝到服务器的~/.ssh/authorized_keys文件中方法有如下几种:

1、将公钥通过scp拷贝到服务器上,然后追加到~/.ssh/authorized_keys文件中,这种方式比较麻烦。scp -P 22 ~/.ssh/id_rsa.pub user@host:~/。

2、通过ssh-copy-id命令最简单,也是第一种方法,ssh-copy-id "-p22 user@host"即可,有时候user@host需要加引号,前面写-p端口号

3、可以通过cat ~/.ssh/id_rsa.pub | ssh -p 22 user@host ‘cat >> ~/.ssh/authorized_keys',这个也是比较常用的方法,因为可以更改端口号。

4.2 基于公钥密钥的 SSHClient 方式登录

进入路径查看我本地id_rsa文件路径

Python paramiko 模块浅谈与SSH主要功能模拟解析

import paramiko
private_key = paramiko.RSAKey.from_private_key_file('/Users/ljf/.ssh/id_rsa')
# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='192.168.199.146', port=22, username='fishman', pkey=private_key)
# 执行命令
stdin, stdout, stderr = ssh.exec_command('df')
# 获取命令结果
res,err = stdout.read(),stderr.read()
result = res if res else err
print(result.decode())
# 关闭连接
ssh.close()

同理。可以用transport封装

import paramiko
private_key = paramiko.RSAKey.from_private_key_file('/Users/ljf/.ssh/id_rsa')
# 实例化一个transport对象
transport = paramiko.Transport(('192.168.199.146', 22))
# 建立连接
transport.connect(username='fishman', pkey=private_key)
ssh = paramiko.SSHClient()
ssh._transport = transport
stdin, stdout, stderr = ssh.exec_command('df')
# 获取命令结果
res,err = stdout.read(),stderr.read()
result = res if res else err
print(result.decode())
# 关闭连接
ssh.close()

同理,可以直接根据私钥字符串连接,首先在本地获取私钥字符串

➜ .ssh cat id_rsa -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAskNhrZGynBQD/5F//uuXvdUPBCfrcKcqoxAc5VZmdpscvGcO 2/wH3letHoZaAqu6edtSBiWl1m6925MuyZY3Ose3AGbEVu5mUTxXpT2GuYieJSLI VN0cIW02FukcqxviJxd6IJye24IKT5iW1hcaqqWcHZBIpaZ79PvG9e360mxdcWkE Iee7w4xu/Ma9KcrNjAc8paq7NUTYk3Ec/OsyU+0m7o2GP26YlAe/MOOgpkZcMxzp PGYNIXHoKkjB426EMoZEl9MXBb9mSx5uRqX22t/OtzPutkNa9lPkFuSotX957BsB 1kCEbhzVpXVM1imET7CiR1b8BcJGAxt7GWTFkQIDAQABAoIBAH54j7Q0yiMxkCSh dc3GF8H2htDMAZ3K+9T0eYu74LYFFj4UX9Zy2KJGUex2JSX/8CzEDU2PKDkaGFjP 80HR8R0i1BLU1jdWrAC2bvgszoiTBKAULU0IEg0lDlryyAQdpDVX0q2QcKQLfoU6 HMmHWsP2+ut+kgv0Mb19Y4rXbDwctmx53BJ0Ykk3RaQe8FiLOAAdFzxbGIUdIwLh N8PEh9HW/wMFvJVEAgNu3oD0bONH+PZKasxqnOQlHrILSPQrNiXBOxCYr9u8cFx7 hl1V0yhQHnCF+JK2se6VXQnJ1pUVtWc3kRTtwas3x7IRPdNJDbj8WT6/n6ocUm+Q OgEY9gECgYEA3CtYVABizz8GsHpged/xDkOKf9gET5m1kX/awdd3m6lkoWboB5OL ym6YwxWpl6Fs0XHRAih3w2434MyTxqdgZf5ixMgq00PBr7itGycokLm1KO1GFjbZ 4tog3qwX6vejHsDl+TMWojxmkEjwQ1uPcQOeY96CvOafHH+kP5zmfAUCgYEAz0Ym 1y07sSfiKSDEO+99r7deex8fssk/xcFI3PgD/4zwu0zGF3QIB124cbZX6Sy6ut0d jzX+RQm5OGUNR1m4Qg1syeNIEF/2mV0rL7+qPGIpYIsuoeuBwedNj7qTIDx4wKtm aJcwdErEQwRJ7UOX9KEdPkKivyf4A+uT5fCsJR0CgYBE7tFF46UMLDiE8pvYLLRF egIYCuM2pPKDLpuoSzToqL2YBycokBqZc80ib1rc3a67WL5OxarRpmWaXZL7BJaa +G2mHOHDqZgv00tnj/gUcAB3Yuqps9y+OPtHnGwUphoNW+nk/wjcHLsj+6I2BKnB gZeKvzUBvdcdTh13yUEknQKBgHBkmNEbPP/+IXutwdrCLYQnyXq30Mdwqzz/ZxQz BHABK9RUeCHlkCj2X/qBJsBQudxz5ABxBbTH5gC3gvDKrMhcYT5EGSKP9rcIt09H /faKP+eS8TFp882CMCOcxwS25b+L8ZcLTIHyvOOeIrweZ/qFlsbY+UjwUmNFzcfk rmPdAoGBAJ9NWhf16aLQxUrPkUvHK9k7ONUadamBxA6NNvHMZxow81/p9VQK71o7 iUdJmC/+VOvGqbA3AbtqkbjBMUWGjEeVKLxMnCZngfu9J6bnWDUaYbQz3gVY63ca KFWjRXO6GtynW0Dec0Nj/q22V5J+2ZCkIvSAQ+cI04d0Ij7RdKPl -----END RSA PRIVATE KEY----- ➜ .ssh

#!/usr/bin/env python # -*- coding: utf-8 -*- # 基于私钥字符串进行连接 import paramiko from io import StringIO key_str = """-----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAskNhrZGynBQD/5F//uuXvdUPBCfrcKcqoxAc5VZmdpscvGcO 2/wH3letHoZaAqu6edtSBiWl1m6925MuyZY3Ose3AGbEVu5mUTxXpT2GuYieJSLI VN0cIW02FukcqxviJxd6IJye24IKT5iW1hcaqqWcHZBIpaZ79PvG9e360mxdcWkE Iee7w4xu/Ma9KcrNjAc8paq7NUTYk3Ec/OsyU+0m7o2GP26YlAe/MOOgpkZcMxzp PGYNIXHoKkjB426EMoZEl9MXBb9mSx5uRqX22t/OtzPutkNa9lPkFuSotX957BsB 1kCEbhzVpXVM1imET7CiR1b8BcJGAxt7GWTFkQIDAQABAoIBAH54j7Q0yiMxkCSh dc3GF8H2htDMAZ3K+9T0eYu74LYFFj4UX9Zy2KJGUex2JSX/8CzEDU2PKDkaGFjP 80HR8R0i1BLU1jdWrAC2bvgszoiTBKAULU0IEg0lDlryyAQdpDVX0q2QcKQLfoU6 HMmHWsP2+ut+kgv0Mb19Y4rXbDwctmx53BJ0Ykk3RaQe8FiLOAAdFzxbGIUdIwLh N8PEh9HW/wMFvJVEAgNu3oD0bONH+PZKasxqnOQlHrILSPQrNiXBOxCYr9u8cFx7 hl1V0yhQHnCF+JK2se6VXQnJ1pUVtWc3kRTtwas3x7IRPdNJDbj8WT6/n6ocUm+Q OgEY9gECgYEA3CtYVABizz8GsHpged/xDkOKf9gET5m1kX/awdd3m6lkoWboB5OL ym6YwxWpl6Fs0XHRAih3w2434MyTxqdgZf5ixMgq00PBr7itGycokLm1KO1GFjbZ 4tog3qwX6vejHsDl+TMWojxmkEjwQ1uPcQOeY96CvOafHH+kP5zmfAUCgYEAz0Ym 1y07sSfiKSDEO+99r7deex8fssk/xcFI3PgD/4zwu0zGF3QIB124cbZX6Sy6ut0d jzX+RQm5OGUNR1m4Qg1syeNIEF/2mV0rL7+qPGIpYIsuoeuBwedNj7qTIDx4wKtm aJcwdErEQwRJ7UOX9KEdPkKivyf4A+uT5fCsJR0CgYBE7tFF46UMLDiE8pvYLLRF egIYCuM2pPKDLpuoSzToqL2YBycokBqZc80ib1rc3a67WL5OxarRpmWaXZL7BJaa +G2mHOHDqZgv00tnj/gUcAB3Yuqps9y+OPtHnGwUphoNW+nk/wjcHLsj+6I2BKnB gZeKvzUBvdcdTh13yUEknQKBgHBkmNEbPP/+IXutwdrCLYQnyXq30Mdwqzz/ZxQz BHABK9RUeCHlkCj2X/qBJsBQudxz5ABxBbTH5gC3gvDKrMhcYT5EGSKP9rcIt09H /faKP+eS8TFp882CMCOcxwS25b+L8ZcLTIHyvOOeIrweZ/qFlsbY+UjwUmNFzcfk rmPdAoGBAJ9NWhf16aLQxUrPkUvHK9k7ONUadamBxA6NNvHMZxow81/p9VQK71o7 iUdJmC/+VOvGqbA3AbtqkbjBMUWGjEeVKLxMnCZngfu9J6bnWDUaYbQz3gVY63ca KFWjRXO6GtynW0Dec0Nj/q22V5J+2ZCkIvSAQ+cI04d0Ij7RdKPl -----END RSA PRIVATE KEY-----""" private_key = paramiko.RSAKey(file_obj=StringIO(key_str)) transport = paramiko.Transport(('192.168.199.146', 22)) transport.connect(username='fishman', pkey=private_key) ssh = paramiko.SSHClient() ssh._transport = transport stdin, stdout, stderr = ssh.exec_command('df') res,err = stdout.read(),stderr.read() result = res if res else err print(result.decode()) # 关闭连接 ssh.close()

以上得到的结果都相同

这里需要注意,如果你是Linux及OSX系统,那么自带SSH,以上操作都没问题,如果你是Windows,那么通过Xsheel也可以生成一个,通过Xsheel--》工具--》新建用户秘钥生成向导,

如果没有装Xsheel,可以将Linux的公钥copy过来,这样在这里可以读取本地存的公钥信息

通过命令sz ~/.ssh/id_rsa,将公钥保存为一个txt文件,paramiko.RSAKey.from_private_key_file(公钥文件)

五,SFTPClient用于连接远程服务器并执行上传下载

我们计划将本地LocalFile.txt上传到fishman机器的test路径下remote.txt,这是该路径下原来的文件,其中remote.txt为空,没有内容,通过sftp.put('LocalFile.txt', '/home/fishman/test/remote.txt')即可上传

Python paramiko 模块浅谈与SSH主要功能模拟解析

基于用户名密码上传下载

import paramiko
# 实例化一个trans对象# 实例化一个transport对象
transport = paramiko.Transport(('192.168.199.146', 22))
# 建立连接
transport.connect(username='fishman', password='9')
# 实例化一个 sftp对象,指定连接的通道
sftp = paramiko.SFTPClient.from_transport(transport)
 
# LocalFile.txt 上传至服务器 /home/fishman/test/remote.txt
# sftp.put('LocalFile.txt', '/home/fishman/test/remote.txt')
# 将LinuxFile.txt 下载到本地 fromlinux.txt文件中
sftp.get('/home/fishman/test/LinuxFile.txt', 'fromlinux.txt')
transport.close()

同理,我们可以下载远程机器上test路径下的LinuxFile.txt文件到本地fromLinux.txt

基于公钥密钥上传下载

import paramiko
private_key = paramiko.RSAKey.from_private_key_file('/Users/ljf/.ssh/id_rsa')
transport = paramiko.Transport(('192.168.199.146', 22))
transport.connect(username='fishman', password='9')
sftp = paramiko.SFTPClient.from_transport(transport)
 
# LocalFile.txt 上传至服务器 /home/fishman/test/remote.txt
# sftp.put('LocalFile.txt', '/home/fishman/test/remote.txt')
# 将LinuxFile.txt 下载到本地 fromlinux.txt文件中
sftp.get('/home/fishman/test/LinuxFile.txt', 'fromlinux.txt')
 
transport.close()

5 实现输入命令立马返回结果的功能 以上操作都是基本的连接,如果我们想实现一个类似xshell工具的功能,登录以后可以输入命令回车后就返回结果:

import paramiko
import os
import select
import sys
 
# 建立一个socket
trans = paramiko.Transport(('192.168.2.129', 22))
# 启动一个客户端
trans.start_client()
 
# 如果使用rsa密钥登录的话
'''
default_key_file = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')
prikey = paramiko.RSAKey.from_private_key_file(default_key_file)
trans.auth_publickey(username='super', key=prikey)
'''
# 如果使用用户名和密码登录
trans.auth_password(username='super', password='super')
# 打开一个通道
channel = trans.open_session()
# 获取终端
channel.get_pty()
# 激活终端,这样就可以登录到终端了,就和我们用类似于xshell登录系统一样
channel.invoke_shell()
# 下面就可以执行你所有的操作,用select实现
# 对输入终端sys.stdin和 通道进行监控,
# 当用户在终端输入命令后,将命令交给channel通道,这个时候sys.stdin就发生变化,select就可以感知
# channel的发送命令、获取结果过程其实就是一个socket的发送和接受信息的过程
while True:
 readlist, writelist, errlist = select.select([channel, sys.stdin,], [], [])
 # 如果是用户输入命令了,sys.stdin发生变化
 if sys.stdin in readlist:
 # 获取输入的内容
 input_cmd = sys.stdin.read(1)
 # 将命令发送给服务器
 channel.sendall(input_cmd)
 
 # 服务器返回了结果,channel通道接受到结果,发生变化 select感知到
 if channel in readlist:
 # 获取结果
 result = channel.recv(1024)
 # 断开连接后退出
 if len(result) == 0:
  print("\r\n**** EOF **** \r\n")
  break
 # 输出到屏幕
 sys.stdout.write(result.decode())
 sys.stdout.flush()
 
# 关闭通道
channel.close()
# 关闭链接
trans.close()

6 支持tab自动补全

import paramiko
import os
import select
import sys
import tty
import termios
 
'''
实现一个xshell登录系统的效果,登录到系统就不断输入命令同时返回结果
支持自动补全,直接调用服务器终端
'''
# 建立一个socket
trans = paramiko.Transport(('192.168.2.129', 22))
# 启动一个客户端
trans.start_client()
 
# 如果使用rsa密钥登录的话
'''
default_key_file = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')
prikey = paramiko.RSAKey.from_private_key_file(default_key_file)
trans.auth_publickey(username='super', key=prikey)
'''
# 如果使用用户名和密码登录
trans.auth_password(username='super', password='super')
# 打开一个通道
channel = trans.open_session()
# 获取终端
channel.get_pty()
# 激活终端,这样就可以登录到终端了,就和我们用类似于xshell登录系统一样
channel.invoke_shell()
 
# 获取原操作终端属性
oldtty = termios.tcgetattr(sys.stdin)
try:
 # 将现在的操作终端属性设置为服务器上的原生终端属性,可以支持tab了
 tty.setraw(sys.stdin)
 channel.settimeout(0)
 
 while True:
 readlist, writelist, errlist = select.select([channel, sys.stdin,], [], [])
 # 如果是用户输入命令了,sys.stdin发生变化
 if sys.stdin in readlist:
  # 获取输入的内容,输入一个字符发送1个字符
  input_cmd = sys.stdin.read(1)
  # 将命令发送给服务器
  channel.sendall(input_cmd)
 
 # 服务器返回了结果,channel通道接受到结果,发生变化 select感知到
 if channel in readlist:
  # 获取结果
  result = channel.recv(1024)
  # 断开连接后退出
  if len(result) == 0:
  print("\r\n**** EOF **** \r\n")
  break
  # 输出到屏幕
  sys.stdout.write(result.decode())
  sys.stdout.flush()
finally:
 # 执行完后将现在的终端属性恢复为原操作终端属性
 termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
 
# 关闭通道
channel.close()
# 关闭链接
trans.close()

到此这篇关于Python paramiko 模块详解与SSH主要功能模拟的文章就介绍到这了,更多相关Python paramiko 模块与SSH内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python使用sorted函数对列表进行排序的方法
Apr 04 Python
Python自动扫雷实现方法
Jul 25 Python
python连接mysql实例分享
Oct 09 Python
Python中关键字global和nonlocal的区别详解
Sep 03 Python
对python当中不在本路径的py文件的引用详解
Dec 15 Python
详解Python Matplotlib解决绘图X轴值不按数组排序问题
Aug 05 Python
Python Web框架之Django框架cookie和session用法分析
Aug 16 Python
详解Python可视化神器Yellowbrick使用
Nov 11 Python
Python FFT合成波形的实例
Dec 04 Python
通俗讲解python 装饰器
Sep 07 Python
Python游戏开发实例之graphics实现AI五子棋
Nov 01 Python
python自动获取微信公众号最新文章的实现代码
Jul 15 Python
python 中的paramiko模块简介及安装过程
Feb 29 #Python
python中使用paramiko模块并实现远程连接服务器执行上传下载功能
Feb 29 #Python
vue学习笔记之动态组件和v-once指令简单示例
Feb 29 #Python
Python实现动态给类和对象添加属性和方法操作示例
Feb 29 #Python
Python使用type动态创建类操作示例
Feb 29 #Python
Django框架静态文件处理、中间件、上传文件操作实例详解
Feb 29 #Python
Python编程快速上手——强口令检测算法案例分析
Feb 29 #Python
You might like
php判断上传的Excel文件中是否有图片及PHPExcel库认识
2013/01/11 PHP
深入php-fpm的两种进程管理模式详解
2013/06/03 PHP
JS拖动技术 关于setCapture使用
2010/12/09 Javascript
jquery+javascript编写国籍控件
2015/02/12 Javascript
深入理解JavaScript系列(26):设计模式之构造函数模式详解
2015/03/03 Javascript
jQuery实现的经典滑动门效果
2015/09/22 Javascript
JavaScript检查子字符串是否在字符串中的方法
2016/02/03 Javascript
全面了解JavaScript的数据类型转换
2016/07/01 Javascript
Node.js的文件权限及读写flag详解
2016/10/11 Javascript
html、css和jquery相结合实现简单的进度条效果实例代码
2016/10/24 Javascript
Sortable.js拖拽排序使用方法解析
2016/11/04 Javascript
Nodejs下用submit提交表单提示cannot post错误的解决方法
2016/11/21 NodeJs
基于bootstrap实现收缩导航条
2017/03/17 Javascript
Angularjs 实现移动端在线测评效果(推荐)
2017/04/05 Javascript
node.js学习之断言assert的使用示例
2017/09/28 Javascript
vue组件编写之todolist组件实例详解
2018/01/22 Javascript
JS中call()和apply()的功能及用法实例分析
2019/06/28 Javascript
JS面向对象编程——ES6 中class的继承用法详解
2020/03/03 Javascript
[01:00]选手抵达华西村 整装待发备战2016国际邀请赛中国区预选赛
2016/06/25 DOTA
Python中logging模块的用法实例
2014/09/29 Python
浅谈python jieba分词模块的基本用法
2017/11/09 Python
Python实现批量读取图片并存入mongodb数据库的方法示例
2018/04/02 Python
值得收藏的10道python 面试题
2019/04/15 Python
python游戏开发之视频转彩色字符动画
2019/04/26 Python
python多进程(加入进程池)操作常见案例
2019/10/21 Python
python socket 聊天室实例代码详解
2019/11/14 Python
python3 dict ndarray 存成json,并保留原数据精度的实例
2019/12/06 Python
中粮集团旗下食品网上购物网站:我买网
2016/09/22 全球购物
学习十八大报告感言
2014/02/04 职场文书
餐厅总厨求职信
2014/03/04 职场文书
2014年小学校长工作总结
2014/12/08 职场文书
应届毕业生自荐信
2015/03/04 职场文书
护士自荐信范文
2015/03/25 职场文书
业务内勤岗位职责
2015/04/13 职场文书
2015年导购员工作总结
2015/04/25 职场文书
SpringBoot工程下使用OpenFeign的坑及解决
2021/07/02 Java/Android