一、动态导入模块

知道一个模块名的字符串形式,通过字符串来导入模块

 mod = __import__("lib.aa")
print(mod) instance = getattr(mod.aa, "C") obj = instance()
print(obj.name)

__import__("lib.aa")看起来是导入了lib.aa,实际上只导入了lib

下面是官方建议的用法

 import importlib
importlib.import_module("lib.aa") #这里就直接导入了lib.aa

二、断言

import importlib
importlib.import_module("lib.aa") obj = aa.C() assert type(obj.name) is str #assert就是断言
print("dddd")

上面表示我断定obj.name就是str,如果正确程序往下走,如果错误直接报错AssertionError

三、通过socket实现SSH功能

server端:

 import socket ,os,time
server = socket.socket()
server.bind(('localhost',9999) ) server.listen() while True:
conn, addr = server.accept()
print("new conn:",addr)
while True:
print("等待新指令")
data = conn.recv(1024)
if not data:
print("客户端已断开")
break
print("执行指令:",data)
cmd_res = os.popen(data.decode()).read() #接受字符串,执行结果也是字符串
print("before send",len(cmd_res))
if len(cmd_res) ==0:
cmd_res = "cmd has no output..." conn.send( str(len(cmd_res.encode())).encode("utf-8") ) #先发大小给客户端
#time.sleep(0.5) #lowb防粘包
client_ack = conn.recv(1024) #等待客户端应答,高端防粘包
conn.send(cmd_res.encode("utf-8"))
print("send done")
os.path.isfile()
os.stat("sock")
server.close()

client端:

 import socket
client = socket.socket() client.connect(('localhost',9999)) while True:
cmd = input(">>:").strip()
if len(cmd) == 0: continue
client.send(cmd.encode("utf-8"))
cmd_res_size = client.recv(1024) ##接受命令结果的长度
print("命令结果大小:",cmd_res_size)
client.send("准备好接受".encode("utf-8")) #防粘包
received_size = 0
received_data = b''
while received_size < int(cmd_res_size.decode()) :
data = client.recv(1024)
received_size += len(data) #每次收到的有可能小于1024,所以必须用len判断
#print(data.decode())
received_data += data
else:
print("cmd res receive done...",received_size)
print(received_data.decode()) client.close()

四、通过socket实现FTP功能

client端:

 import socket
import hashlib client = socket.socket() client.connect(('localhost', 9999)) while True:
cmd = input(">>:").strip()
if len(cmd) == 0: continue
if cmd.startswith("get"):
client.send(cmd.encode())
server_response = client.recv(1024)
print("servr response:", server_response)
client.send(b"ready to recv file")
file_total_size = int(server_response.decode())
received_size = 0
filename = cmd.split()[1]
f = open(filename + ".new", "wb")
m = hashlib.md5() while received_size < file_total_size:
if file_total_size - received_size > 1024: # 要收不止一次
size = 1024
else: # 最后一次了,剩多少收多少
size = file_total_size - received_size
print("last receive:", size) data = client.recv(size)
received_size += len(data)
m.update(data) # 记录MD5
f.write(data)
# print(file_total_size,received_size)
else:
new_file_md5 = m.hexdigest()
print("file recv done", received_size, file_total_size)
f.close()
server_file_md5 = client.recv(1024)
print("server file md5:", server_file_md5) # 输出服务端文件MD5
print("client file md5:", new_file_md5) # 输出传过来的文件的MD5 client.close()

server端:

 import hashlib
import socket ,os,time
server = socket.socket()
server.bind(('0.0.0.0',9999) )
server.listen()
while True:
conn, addr = server.accept()
print("new conn:",addr)
while True:
print("等待新指令")
data = conn.recv(1024)
if not data:
print("客户端已断开")
break
cmd,filename = data.decode().split()
print(filename)
if os.path.isfile(filename):
f = open(filename,"rb")
m = hashlib.md5()
file_size = os.stat(filename).st_size
conn.send( str(file_size).encode() ) #send file size
conn.recv(1024) #wait for ack
for line in f:
m.update(line)
conn.send(line)
print("file md5", m.hexdigest())
f.close()
conn.send(m.hexdigest().encode()) #send md5
print("send done") server.close()

五、通过SocketServer实现多并发

The socketserver module simplifies the task of writing network servers.

There are four basic concrete server classes:

 class socketserver.TCPServer(server_address, RequestHandlerClass, bind_and_activate=True)

This uses the Internet TCP protocol, which provides for continuous streams of data between the client and server. If bind_and_activate is true, the constructor automatically attempts to invoke server_bind() andserver_activate(). The other parameters are passed to the BaseServer base class.

 class socketserver.UDPServer(server_address, RequestHandlerClass, bind_and_activate=True)

This uses datagrams, which are discrete packets of information that may arrive out of order or be lost while in transit. The parameters are the same as for TCPServer.

 class socketserver.UnixStreamServer(server_address, RequestHandlerClass, bind_and_activate=True)
class socketserver.UnixDatagramServer(server_address, RequestHandlerClass,bind_and_activate=True)

These more infrequently used classes are similar to the TCP and UDP classes, but use Unix domain sockets; they’re not available on non-Unix platforms. The parameters are the same as for TCPServer.

These four classes process requests synchronously; each request must be completed before the next request can be started. This isn’t suitable if each request takes a long time to complete, because it requires a lot of computation, or because it returns a lot of data which the client is slow to process. The solution is to create a separate process or thread to handle each request; the ForkingMixIn and ThreadingMixIn mix-in classes can be used to support asynchronous behaviour.

There are five classes in an inheritance diagram, four of which represent synchronous servers of four types:

+------------+
| BaseServer |
+------------+
|
v
+-----------+ +------------------+
| TCPServer |------->| UnixStreamServer |
+-----------+ +------------------+
|
v
+-----------+ +--------------------+
| UDPServer |------->| UnixDatagramServer |
+-----------+ +--------------------+

创建一个socketserver 至少分以下几步:

  1. First, you must create a request handler class by subclassing the BaseRequestHandlerclass and overriding its handle() method; this method will process incoming requests.   
  2. Second, you must instantiate one of the server classes, passing it the server’s address and the request handler class.
  3. Then call the handle_request() orserve_forever() method of the server object to process one or many requests.
  4. Finally, call server_close() to close the socket.

基本的socketserver代码

 import socketserver

 class MyTCPHandler(socketserver.BaseRequestHandler):
"""
The request handler class for our server. It is instantiated once per connection to the server, and must
override the handle() method to implement communication to the
client.
""" def handle(self):
# self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).strip()
print("{} wrote:".format(self.client_address[0]))
print(self.data)
# just send back the same data, but upper-cased
self.request.sendall(self.data.upper()) if __name__ == "__main__":
HOST, PORT = "localhost", 9999 # Create the server, binding to localhost on port 9999
server = socketserver.TCPServer((HOST, PORT), MyTCPHandler) # Activate the server; this will keep running until you
# interrupt the program with Ctrl-C
server.serve_forever()

上面的代码虽然使用了socketserver,但是依然不能实现多并发,我们要想实现多并发通信,需要用到下面这些多并发类

class socketserver.ForkingTCPServer

class socketserver.ForkingUDPServer

class socketserver.ThreadingTCPServer

class socketserver.ThreadingUDPServer

我们只需要把上面的代码中的

 server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)

替换为:

 server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)

就可以实现多线程多并发了

下面我们举个栗子:

 import socketserver

 class MyTCPHandler(socketserver.BaseRequestHandler):
def handle(self):
while True:
try:
self.data = self.request.recv(1024).strip()
print("{} wrote:".format(self.client_address[0]))
print(self.data)
self.request.send(self.data.upper())
except ConnectionResetError as e:
print("err",e)
break
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
# Create the server, binding to localhost on port 9999
server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)
server.serve_forever()

进击的Python【第八章】:动态导入模块、断言、socket开发之SSH,FTP的更多相关文章

  1. python学习之-- 动态导入模块

    python 动态导入模块方法1: __import__ 说明: 1. 函数功能用于动态的导入模块,主要用于反射或者延迟加载模块. 2. __import__(module)相当于import mod ...

  2. python网络编程-动态导入和断言

    一:动态导入importlib 在程序运行的过程中,根据变量或者配置动态的决定导入哪个模块,可以使用模块importlib importlib使用示例 二:断言assert 如果接下来的程序依赖于前面 ...

  3. Python 动态导入模块

    动态导入模块 目录结构: zhangsandeMacBook-Air:1110 zhangsan$ tree . . ├── lib │   └── aa.py ├── test1.py lib目录下 ...

  4. Python importlib(动态导入模块)

    使用 Python importlib(动态导入模块) 可以将字符串型的模块名导入 示例: import importlib module = 'module name' # 字符串型模块名 test ...

  5. python 反射 动态导入模块 类attr属性

    1.反射 hasattr getattr delattr setattr 优点:事先定义好接口,接口只有在被完成后才能真正执行,这实现了即插即用,这其实是一种“后期绑定”,即先定义好接口, 然后是再去 ...

  6. python动态导入模块——importlib

    当在写代码时,我们希望能够根据传入的选项设置,如args.model来确定要导入使用的是哪个model.py文件,而不是一股脑地导入 这种时候就需要用上python的动态导入模块 比如此时文件结构为: ...

  7. python中schedule模块的简单使用 || importlib.import_module动态导入模块

    1 import schedule 2 import time 3 4 def start(): #定义一个函数 5 print("****") 6 7 8 if __name__ ...

  8. Python 实现接口类的两种方式+邮件提醒+动态导入模块+反射(参考Django中间件源码)

    实现接口类的两种方式 方式一 from abc import ABCMeta from abc import abstractmethod class BaseMessage(metaclass=AB ...

  9. Python 实现抽象类的两种方式+邮件提醒+动态导入模块+反射(参考Django中间件源码)

    实现抽象类的两种方式 方式一 from abc import ABCMeta from abc import abstractmethod class BaseMessage(metaclass=AB ...

随机推荐

  1. 【.Net Core 学习系列】-- EF Core 实践(Code First)

    一.开发环境: VS2015, .Net Core 1.0.0-preview2-003156 二解决方案: 新建项目: File --> New --> Project -->   ...

  2. BZOJ 1055 HAOI2008 玩具取名 动态规划

    题目大意:给定一个由'W','I','N','G'构成的字符串.给定一些规则.这些规则能够将两个字符合成为一个,比如"II"能够合成为'W',"WW"能够合成为 ...

  3. win8系统 重装系统如何删除EFI分区

    在PE下(一般重装系统就是在PE下),依次输入如下命令(注意虽然显示的是中文名"磁盘0",但是还是用英文disk 0) list disk select disk 0 clean

  4. JAVA学习第六十四课 — 反射机制

       Java反射机制是在执行状态中,对于随意一个类,都可以知道这个类的全部属性和方法,对于随意一个对象,都可以调用它的随意一个方法和属性,这样的动态获取的信息以及动态调用对象的方法的功能称为java ...

  5. Centos 6.4 搭建LANMP一键安装版

    lanmp一键安装包是wdlinux官网2010年开始推出的lamp,lnmp,lnamp(apache,nginx,php,mysql,zend,eAccelerator,pureftpd)应用环境 ...

  6. python3 base64模块代码分析

    #! /usr/bin/env python3 """Base16, Base32, Base64 (RFC 3548), Base85 and Ascii85 data ...

  7. windows下使用mingw和msys编译GOTOBLAS和OpenBLAS

    在windows下利用msys编译openBLAS若遇到错误提示: gcc: CreateProcess : No such file or directory 问题原因参考:http://www.c ...

  8. Mac下Apache+MySQL+PHP安装

    max下是自带有Apache和php的服务器的,不需要另外安装,本文就对相关配置进行介绍. 第一:Apache 在终端中输入,下面指令即可启动Apache服务器: //启动 sudo apachect ...

  9. 【iOS系列】-autorelease的作用

    内存管理原则(配对原则):只要出现了new,alloc,retain方法,就要配对出现release,autorelease   1:对象存入到自动释放池中,当这个池子被销毁的时候他会对池子中所有的对 ...

  10. 我的Android进阶之旅------&gt;Android编译错误java.util.zip.ZipException: duplicate entry的解决方法

    今天在Android Studio中把另外一个项目引入当前项目,编译的时候出现了java.util.zip.ZipException: duplicate entry错误. 错误例如以下所看到的: F ...