目录

一、反射

二、socket

三、socketserver


一、反射

python中的反射功能是由以下四个内置函数提供:hasattr、getattr、setattr、delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员、获取成员、设置成员、删除成员。

 class Foo(object):

     def __init__(self):
self.name = 'wupeiqi' def func(self):
return 'func' obj = Foo() # #### 检查是否含有成员 ####
hasattr(obj, 'name')
hasattr(obj, 'func') # #### 获取成员 ####
getattr(obj, 'name')
getattr(obj, 'func') # #### 设置成员 ####
setattr(obj, 'age', 18)
setattr(obj, 'show', lambda num: num + 1) # #### 删除成员 ####
delattr(obj, 'name')
delattr(obj, 'func')

详细解析:

当我们要访问一个对象的成员时,应该是这样操作:

 class Foo(object):                                                 

     def __init__(self):
self.name = 'tom' def func(self):
return 'func' obj = Foo() # 访问字段
obj.name
# 执行方法
obj.func()

那么问题来了?
a、上述访问对象成员的 name 和 func 是什么? 
答:是变量名
b、obj.xxx 是什么意思? 
答:obj.xxx 表示去obj中或类中寻找变量名 xxx,并获取对应内存地址中的内容。
c、需求:请使用其他方式获取obj对象中的name变量指向内存中的值 “tom”
 class Foo(object):

     def __init__(self):
self.name = 'tom' # 不允许使用 obj.name
obj = Foo()

答:有两种方法,如下:

 class Foo(object):

     def __init__(self):
self.name = 'alex' def func(self):
return 'func' # 不允许使用 obj.name
obj = Foo() print obj.__dict__['name']

方法一

 class Foo(object):

     def __init__(self):
self.name = 'alex' def func(self):
return 'func' # 不允许使用 obj.name
obj = Foo() print getattr(obj, 'name')

方法二

d、比较三种访问方式

  • obj.name
  • obj.__dict__['name']
  • getattr(obj, 'name')

答:第一种和其他种比,...
      第二种和第三种比,...

结论:反射是通过字符串的形式操作对象相关的成员。一切事物都是对象!!!

 import sys

 class WebServer(object):
def __init__(self,host,port):
self.host = host
self.port = port def start(self):
print('start') def stop(self):
print("stop") def restart(self):
self.stop()
self.start() if __name__ == "__main__":
server = WebServer('localhost',333)
if hasattr(server,sys.argv[1]):
func = getattr(server,sys.argv[1])
func()

例子

类也是对象

 class Foo(object):

     staticField = "old boy"

     def __init__(self):
self.name = 'wupeiqi' def func(self):
return 'func' @staticmethod
def bar():
return 'bar' print getattr(Foo, 'staticField')
print getattr(Foo, 'func')
print getattr(Foo, 'bar')

模块也是对象

 #!/usr/bin/env python
# -*- coding:utf-8 -*- def dev():
return 'dev'

home.py

 #!/usr/bin/env python
# -*- coding:utf-8 -*- """
程序目录:
home.py
index.py 当前文件:
index.py
""" import home as obj #obj.dev() func = getattr(obj, 'dev')
func()

index.py


二、socket

socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求。

socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用【打开】【读写】【关闭】模式来操作。socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)

socket和file的区别:

  • file模块是针对某个指定文件进行【打开】【读写】【关闭】
  • socket模块是针对 服务器端 和 客户端Socket 进行【打开】【读写】【关闭】

socket服务端与客户端交流示意图:


socket()模块函数

使用socket.socket()函数来创建套接字,语法如下:

socket(socket_family,socket_type,protocol=0)

如前所述,参数一:socket_family(地址簇)

socket.AF_UNIX    只能用于单一的UNIX系统进程间通信

socket.AF_INET     IPV4(默认)

socket.AF_INET6   IPV6

参数二:socket_type(类型)

socket.SOCK_STREAM 流式socket , for TCP (默认)
socket.SOCK_DGRAM 数据报式socket , for UDP

socket.SOCK_RAW 原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。

socket.SOCK_RDM 是一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用。

socket.SOCK_SEQPACKET 可靠的连续数据包服务

参数三:protocol(协议)

0 (默认)与特定的地址家族相关的协议,如果是 0 ,则系统就会根据地址格式和套接类别,自动选择一个合适的协议

创建一个TCP/IP的套接字,你要这样调用socket.socket():

tcpsocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

同样的,创建一个UDP/IP的套接字,你要这样:

udpsocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

套接字对象(内建)方法:

函数 描述
服务器套接字函数  
s.bind(address) 绑定地址(主机名,端口号对)到套接字
s.listen(backlog) 开始TCP监听
s.accept() 被动接受TCP客户端连接,(阻塞式)等待链接的到来
客户端套接字函数  
s.connect() 主动初始化TCP服务器连接
s.connect_ex() connect()函数的扩展版本,出错时返回出错码,而不是抛出异常
公共用途的套接字函数  
s.recv() 接收TCP数据
s.send() 发送TCP数据
s.sendall() 完整发送TCP数据(不停调用s.send())
s.recvfrom() 接收UDP数据
s.sendto() 发送UDP数据
s.getpeername() 链接到当前套接字的远端的地址(TCP连接)
s.getsockname() 当前套接字的地址
s.getsockopt() 返回指定套接字的参数
s.setsockopt() 设置指定套接字的参数
s.close() 关闭套接字
面向模块的套接字函数  
s.setblocking() 设置套接字的阻塞与非阻塞模式
s.settimeout() 设置阻塞套接字操作的超时时间
s.gettimeout() 得到阻塞套接字操作的超时时间
面向文件的套接字函数  
s.fileno() 套接字的文件描述
s.makefile() 创建一个与该套接字相关联的文件对象

例:(win环境)

server端

#!/usr/bin/env python
# -*- coding:utf-8 -*- import socket ip_port = ('127.0.0.1',9999) sk = socket.socket()
sk.bind(ip_port)
sk.listen(5) while True:
print('server waiting...')
conn,addr = sk.accept()
client_data = conn.recv(1024)
print(str(client_data,'utf8'))
conn.sendall(bytes('不要回答,不要回答,不要回答','utf8')) conn.close()

client端

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
ip_port = ('127.0.0.1',9999) sk = socket.socket()
sk.connect(ip_port) sk.sendall(bytes('请求占领地球','utf8')) server_reply = sk.recv(1024)
print(str(server_reply,'utf8')) sk.close()

连续交互通信实例:

server端:(win环境)

#!/usr/bin/env python
# -*- coding:utf-8 -*- import socket ip_port = ('127.0.0.1',9999) sk = socket.socket()
sk.bind(ip_port)
sk.listen(5) while True:
print('server waiting...')
conn,addr = sk.accept()
client_data = conn.recv(1024)
print(str(client_data,'utf8'))
conn.sendall(bytes('不要回答,不要回答,不要回答','utf8'))
while True:
try:
            client_data = conn.recv(1024)
print(str(client_data,'utf8'))
server_response = input('>>>:').strip() except Exception:
            print("client closed,break")
            break
        conn.send(bytes(server_response,'utf8'))
conn.close()

server端:(Linux环境)

#!/usr/bin/env python
# -*- coding:utf-8 -*- import socket ip_port = ('127.0.0.1',9999) sk = socket.socket()
sk.bind(ip_port)
sk.listen(5) while True:
print('server waiting...')
conn,addr = sk.accept()
client_data = conn.recv(1024)
print(str(client_data,'utf8'))
conn.sendall(bytes('不要回答,不要回答,不要回答','utf8'))
while True:
client_data = conn.recv(1024)
print(str(client_data,'utf8'))
        server_response = input('>>>:').strip()
if not client_data:break
conn.send(server_response) conn.close()

client端:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
ip_port = ('127.0.0.1',9999) sk = socket.socket()
sk.connect(ip_port) sk.sendall(bytes('请求占领地球','utf8'))
server_reply = sk.recv(1024)
print(str(server_reply,'utf8'))
while True:
user_input = input(">>>").strip()
sk.send(bytes(user_input,'utf8'))
server_reply = sk.recv(1024)
print(str(server_reply,'utf8')) sk.close()

模拟实现简单ssh功能:

server端:

#!/usr/bin/env python
# -*- coding:utf-8 -*- import socket
import subprocess
ip_port = ('127.0.0.1',9999) sk = socket.socket()
sk.bind(ip_port)
sk.listen(5) while True:
print('server waiting...')
conn,addr = sk.accept()
while True:
client_data = conn.recv(1024)
if not client_data:break
print("recv cmd:",str(client_data,'utf8'))
cmd = str(client_data,'utf8').strip()
cmd_call = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE)
cmd_result = cmd_call.stdout.read()
if len(cmd_result) == 0:
cmd_result = b"cmd execution has no output..."
ack_msg = bytes("CMD_RESULT_SIZE|%s"%len(cmd_result),"utf8")
conn.send(ack_msg)
client_ack = conn.recv(50)
if client_ack.decode() == "CLIENT_READY_TO_RECV":
conn.send(cmd_result) conn.close()

client端:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
ip_port = ('127.0.0.1',9999) sk = socket.socket()
sk.connect(ip_port)
while True:
user_input = input("cmd:").strip()
if len(user_input) == 0:continue
if user_input == "q":break
sk.send(bytes(user_input,'utf8'))
#ack_msg = b"CMD_RESULT_SIZE|%s",len(cmd_result)
server_ack_msg = sk.recv(100)
cmd_res_msg = str(server_ack_msg.decode()).split("|")
print("server response:",cmd_res_msg)
if cmd_res_msg[0] == "CMD_RESULT_SIZE":
cmd_res_size = int(cmd_res_msg[1])
sk.send(b"CLIENT_READY_TO_RECV")
res = ''
received_size = 0
while received_size < cmd_res_size:
data = sk.recv(500)
received_size += len(data)
res += str(data.decode())
else:
print(str(res))
print("----------recv doen----------")
sk.close()

三、sockeserver

SocketServer内部使用 IO多路复用 以及 “多线程” 和 “多进程” ,从而实现并发处理多个客户端请求的Socket服务端。即:每个客户端请求连接到服务器时,Socket服务端都会在服务器是创建一个“线程”或者“进程” 专门负责处理当前客户端的所有请求。

例:

server端:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socketserver
class MyTCPHandler(socketserver.BaseRequestHandler):
def setup(self):
print("Building secure connection chanel...")
def handle(self):
print("New Conn:",self.client_address)
while True: data = self.request.recv(1024)
if not data:break
print("Client Says:",data.decode())
self.request.send(data)
def finish(self):
print("client conn is done...")
if __name__ == '__main__':
HOST, PORT = "localhost", 50007
# 把刚才写的类当作一个参数传给ThreadingTCPServer这个类,下面的代码就创建了一个多线程socket server
server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)
# 启动这个server,这个server会一直运行,除非按ctrl-C停止
server.serve_forever()

client端:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
ip_port = ('127.0.0.1',50007) sk = socket.socket()
sk.connect(ip_port)
while True:
msg = input(">>:").strip()
sk.sendall(bytes(msg,'utf8'))
server_reply = sk.recv(1024)
print("Server Reply:",str(server_reply,'utf8'))
sk.close()

python学习day7的更多相关文章

  1. python学习Day7 数据类型的转换,字符编码演变历程

    一.数据类型的转换 1.1.1.字符转列表:lst1 = str.split(默认空格,也可依据指定字符分界),若无分界字符,就没法拆分,这时可以直接放进list转成列表 ----> s1 = ...

  2. Python学习-day7 类 部分socket

    这周还是继续关于类的学习,在面向对象的学习过程中又学习了网络编程,并且提交了编写FTP的作业. 复习一下类的相关概念和定义 类      属性           实例变量:内存中           ...

  3. python学习day7 数据类型及内置方法补充

    http://www.cnblogs.com/linhaifeng/articles/7133357.html#_label4 1.列表类型 用途:记录多个值(一般存放同属性的值) 定义方法 在[]内 ...

  4. python学习 day7 (3月8日)

    read()读出来了之后文件里就从之后开始  光标不知道在哪 编码的进阶: 背景: ASCII:英文字母,数字,特殊符号,------------>二进制的对应关系 str: 一个字符 ---- ...

  5. python学习-Day7

    目录 作业讲解 数据类型内置方法2 字符串(str) 列表(list) 类型转换 内置方法 索引取值 切片操作 步长 统计列表中元素的个数 成员运算 (in和not in) 列表添加元素的方式* 删除 ...

  6. python学习day7 深浅拷贝&文件操作

    4-4 day07 深浅拷贝&文件操作 .get()用法 返回指定键的值,如果值不在字典中返回默认值. info={'k1':'v1,'K2':'v2'}mes = info.get('k1' ...

  7. Python学习记录day7

    目录 Python学习记录day7 1. 面向过程 VS 面向对象 编程范式 2. 面向对象特性 3. 类的定义.构造函数和公有属性 4. 类的析构函数 5. 类的继承 6. 经典类vs新式类 7. ...

  8. python笔记 - day7

    python笔记 - day7 参考: http://www.cnblogs.com/wupeiqi/articles/5501365.html 面向对象,初级篇: http://www.cnblog ...

  9. 【目录】Python学习笔记

    目录:Python学习笔记 目标:坚持每天学习,每周一篇博文 1. Python学习笔记 - day1 - 概述及安装 2.Python学习笔记 - day2 - PyCharm的基本使用 3.Pyt ...

随机推荐

  1. win7 Oracle 11g安装及安装中遇到的问题

    根据自己的系统从oracle官方下载安装包,官方地址:http://www.oracle.com/index.html win7的oracle 11g 安装包(2个): http://223.20.2 ...

  2. psutil官方文档

    psutil documentation¶ Quick links Home page Install Blog Forum Download Development guide What’s new ...

  3. Mysql基本类型(字符串类型)——mysql之二

    转自: http://www.cnblogs.com/doit8791/archive/2012/05/28/2522556.html 1.varchar类型的变化 MySQL 数据库的varchar ...

  4. < IOS > X-code 5.1 x86 - 64 编译问题

    关于xcode 5.1   x86 - 64 编译问题   坐等了N久,终于IOS 7.1 发布了,作为一个果粉,忍不住第一时间升级了.结果用设备测试的时候,出问题了,一直检测不到设备,哈哈,纠结了半 ...

  5. UVA 100 - The 3n+1 problem (3n+1 问题)

    100 - The 3n+1 problem (3n+1 问题) /* * 100 - The 3n+1 problem (3n+1 问题) * 作者 仪冰 * QQ 974817955 * * [问 ...

  6. Restful风格的springMVC配搭ajax请求的小例子

    1. GET请求的例子 ajax代码: 请求参数拼接在url后面(参数在服务器可通过HttpServletRequest获取,也可以直接通过@RequestParam自动注入,参考DELETE例子的方 ...

  7. Spring(二)——IoC

    IoC(Inversion of Control)称之为控制反转,指的是在Spring框架的配置文件中声明对象,由框架负责创建对象,这叫做控制反转.实现方式有两种:DI(Dependency Inje ...

  8. Spring-Junit4

      Spring整合Junit4测试Service 1. 加入依赖包 使用Spring的测试框架需要加入以下依赖包: JUnit 4 (官方下载:https://github.com/KentBeck ...

  9. vector之妙用系列

    vector用法: 总结了下大家写的,感觉用着很方便: vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被认为是一个容器,是 ...

  10. 有一种acm题目叫做,奇葩!

    本文全然没有技术含量,纯粹是娱乐. 我事实上想写点东西.可是近期好像做计算几何做得太多了,一种想说说不出东西的感觉,唯有写一下一些奇葩的题目了. HDU3337:Guess the number pi ...