本篇介绍内容

  • 作用域
  • python类的多继承
  • IO多路复用
  • socketserver之源码剖析
  • 多线程和多进程

作用域

if 1 == 1:
name = "xxx" print(name)

上面代码在python和javascript中没有块级作用域,是可以执行的但是在c#和java中有块级作用域,会报错变量name不存在

python的作用域链

  • 由内向外找
  • 找不到就报错

当程序还没执行作用域在执行之前就已经定义好了,下面的例子证明了这点

name = "aaa"

def f2():
name = "bbb"
def f1():
print(name)
f1()
f2() # 在f2执行之前f1和f2的作用域就已经被定义好了 # 输出
bbb

name = "aaa"
def f1():
print(name) def f2():
name = "bbb"
f1()
f2() # 在f2执行之前f1和f2的作用域就已经被定义好了
# 输出
aaa
name = "aaa"
def f1():
print(name) def f2():
name = "bbb"
return f1 # 在f2函数被执行之前f1和f2的作用域就已经被定义好了
ret = f2()
ret() # 输出
aaa
li = [lambda:x for x in range(10)] 

上面的语句等同于下面的

li = []
for x in range(10): def f1():
return x li.append(f1)
print(li[0]())

多继承

  • python3

  • python2.7

    • 经典类
    • 新式类 继承object

IO多路复用

select poll epoll

IO多路复用底层就是监听socket对象内部是否有变化,是否在收发消息

  • select IO多路复用之监听客户端连接

    • 服务端
    import socket
    import select sk = socket.socket()
    sk.bind(("127.0.0.1", 9999,))
    sk.listen(5) while True:
    rlist, w, e = select.select([sk, ], [], [], 5)
    # 监听sk(服务器端)对象,如果sk对象发生变化,表示有客户端来连接了,此时rlist值为[sk]
    # 监听conn对象,如果conn发生变化,表示客户端有消息发送过来了,此时rlist的值为[客户端]
    print(rlist) for r in rlist:
    print(r)
    conn, address = r.accept()
    conn.sendall(bytes("hello", encoding="utf-8"))
    • 客户端
    import socket
    
    sk = socket.socket()
    sk.connect(("127.0.0.1", 9999,)) data = sk.recv(1024)
    print(data) while True:
    input(">>") sk.close()
  • select IO多路复用之监听客户端连接以及接收客户端发送的数据

    • 服务端
    import socket
    import select sk = socket.socket()
    sk.bind(("127.0.0.1", 9999,))
    sk.listen(5) inputs = [sk,]
    while True:
    rlist, w, e = select.select(inputs, [], [], 1)
    # 监听sk(服务器端)对象,如果sk对象发生变化,表示有客户端来连接了,此时rlist值为[sk]
    # 监听conn对象,如果conn发生变化,表示客户端有消息发送过来了,此时rlist的值为[客户端] print(len(inputs), len(rlist)) for r in rlist:
    print(r)
    if r == sk:
    # 有新的客户端连接进来
    conn, address = r.accept()
    inputs.append(conn)
    conn.sendall(bytes("hello", encoding="utf-8"))
    else:
    # 有客户端给我发送数据
    recv_data = r.recv(1024)
    print(recv_data)
    • 客户端
    import socket
    
    sk = socket.socket()
    sk.connect(("127.0.0.1", 9999,)) data = sk.recv(1024)
    print(data) while True:
    inp = input(">>")
    sk.sendall(bytes(inp, encoding='utf-8')) sk.close()
  • select IO多路复用之读写分离

    • 服务端
    import socket
    import select sk = socket.socket()
    sk.bind(("127.0.0.1", 9999,))
    sk.listen(5) inputs = [sk,]
    outputs = [] while True:
    rlist, wlist, e = select.select(inputs, outputs, [], 1)
    # 监听sk(服务器端)对象,如果sk对象发生变化,表示有客户端来连接了,此时rlist值为[sk]
    # 监听conn对象,如果conn发生变化,表示客户端有消息发送过来了,此时rlist的值为[客户端] print(len(inputs), len(rlist)) for r in rlist:
    print(r)
    if r == sk:
    # 有新的客户端连接进来
    conn, address = r.accept()
    inputs.append(conn)
    conn.sendall(bytes("hello", encoding="utf-8"))
    else:
    # 有客户端给我发送数据
    try:
    recv_data = r.recv(1024) if not recv_data: # 某些操作系统,在socket断开的时候,会发送一个空给server,所以要判断空的情况
    raise Exception("断开连接")
    else:
    outputs.append(r)
    except Exception as e:
    inputs.remove(r) for w in wlist:
    w.sendall(bytes("response", encoding="utf-8"))
    outputs.remove(w)
    • 客户端
    import socket
    
    sk = socket.socket()
    sk.connect(("127.0.0.1", 9999,)) data = sk.recv(1024)
    print(data) while True:
    inp = input(">>")
    sk.sendall(bytes(inp, encoding='utf-8'))
    print(sk.recv(1024))
    sk.close()
  • select IO多路复用之读写分离 - 服务端根据客户端的输入返回对应的信息

    • 服务端
    import socket
    import select sk = socket.socket()
    sk.bind(("127.0.0.1", 9999,))
    sk.listen(5) inputs = [sk, ] #
    outputs = []
    messages = {} # 用来存放客户端发送过来的消息,存放格式 连接客户端的对象: 消息 while True:
    rlist, wlist, elist = select.select(inputs, outputs, [sk, ], 1)
    # rlist 监听sk(服务器端)对象,如果sk对象发生变化,表示有客户端来连接了,此时rlist值为[sk]
    # wlist 监听conn对象,如果conn发生变化,表示客户端有消息发送过来了,此时rlist的值为[客户端]
    # elist 监听sk(服务器端)对象是否发生错误 print(len(inputs), len(rlist)) for r in rlist:
    print(r)
    if r == sk:
    # 有新的客户端连接进来
    conn, address = r.accept()
    inputs.append(conn)
    messages[conn] = [] # 在存储消息的字典中创建一个以客户端连接对象为key 空列表为value的键值对
    conn.sendall(bytes("hello", encoding="utf-8"))
    else:
    # 有客户端给我发送数据
    try:
    recv_data = r.recv(1024) if not recv_data: # 某些操作系统,在socket断开的时候,会发送一个空给server,所以要判断空的情况
    raise Exception("断开连接")
    else:
    outputs.append(r)
    messages[r].append(recv_data) except Exception as e:
    inputs.remove(r)
    del messages[r] for w in wlist:
    print(messages[w])
    msg = messages[w].pop()
    resp = msg + bytes("response", encoding="utf-8")
    w.sendall(resp)
    outputs.remove(w)
    • 客户端
    import socket
    
    sk = socket.socket()
    sk.connect(("127.0.0.1", 9999,)) data = sk.recv(1024)
    print(data) while True:
    inp = input(">>")
    sk.sendall(bytes(inp, encoding='utf-8'))
    print(sk.recv(1024))
    sk.close()

socketserver之源码剖析

多线程和多进程

多线程和多进程的定义

  • 一个应用程序,可以有多进程和多线程
  • 默认:单进程,单线程
  • 单进程,多线程
    • IO类型的操作,不占用CPU,使用多线程进行IO操作,提高并发
    • 计算类型的操作,需要CPU计算,使用多进程进行计算型密集的操作提高并发,可以利用上CPU多核的特性
  • GIL全局解释器锁,在java和c#中是不存在GIL的,多线程也可以达到并发

多线程

  • 初识多线程

    • 当没有多线程的时候只能够像下面代码中的这种方式进行工作
    import time
    
    def renwu(renwu_id):
    time.sleep(1)
    print(renwu_id) if __name__ == '__main__':
    for i in range(10):
    renwu(i)
    • 使用多线程进行操作
    import time
    import threading def renwu(renwu_id):
    time.sleep(1)
    print(renwu_id) if __name__ == '__main__':
    for i in range(10):
    t = threading.Thread(target=renwu, args=[i,])
    t.start()
  • 多线程模块下面Thread类的一些方法

getName()	# 获得当前线程对象的名称
ident # 返回一个非0的整数 线程标识符 未运行的返回值为空
is_alive() # 返回一个布尔值,判断线程的存活状态
isDaemon() # 返回一个布尔值,判断线程是否为后台程序
join() # 设置子线程为阻塞模式
setDaemon(daemonic) # 设置对象是否为后台程序,该方法需要在start方法之前,运行需要一个参数,传True或者False
setName(name) # 设置线程的名称
start() # 执行线程,不代表当前线程会被立即执行,什么时候执行由cpu调度决定
  • 模块threading下面的一些函数
threading.active_count()	# 返回当前存活的线程数量,等于threading.enumerate()返回列表的长度
threading.current_thread() # 返回当前主线程对象
threading.enumerate() # 返回一个列表,该列表包括当前处于存活状态的线程对象
threading.get_ident() # 返回一个非0的整数 线程标识符

python学习之路-10 网络编程之进阶的更多相关文章

  1. python的学习之路day7-socket网络编程

    python基础部分学习完了,时间也已经过了两个月左右,感觉没学到什么,可能是我学习之后忘记的太多了. 由于没钱买书,要是去培训就更没钱了,所以在网上找了一本书,感觉还不错,讲的比较好,比较详细. P ...

  2. Python学习之路15☞socket编程

    一 客户端/服务器架构 即C/S架构,包括 1.硬件C/S架构(打印机) 2.软件C/S架构(web服务) C/S架构与socket的关系: 我们学习socket就是为了完成C/S架构的开发 二 os ...

  3. 4月18日 python学习总结 异常处理、网络编程

    一. 异常 1.什么是异常 异常是错误发生的信号,程序一旦出错,如果程序中还没有相应的处理机制 那么该错误就会产生一个异常抛出来,程序的运行也随之终止 2.一个异常分为三部分: 1.异常的追踪信息 2 ...

  4. Python学习(十三) —— 网络编程

    一.操作系统基础 操作系统(Operating System):OS是管理和控制计算机硬件和软件资源的计算机程序,是直接运行在“裸机”上的最基本的系统软件,任何其他软件都必须在操作系统的支持下才能运行 ...

  5. 吴裕雄--天生自然python学习笔记:Python3 网络编程

    Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的全部方法. 高级别的网络 ...

  6. Python学习之路10☞面向对象进阶

    一 isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 1 class Foo(objec ...

  7. python学习笔记(十二)-网络编程

    本文结束使用 Requests 发送网络请求.requests是一个很实用的Python HTTP客户端库,编写爬虫和测试服务器响应数据时经常会用到.可以说,Requests 完全满足如今网络的需求. ...

  8. Python学习之路——类-面向对象编程

    类 面向对象编程 通过类获取一个对象的过程 - 实例化 类名()会自动调用类中的__init__方法 类和对象之间的关系? 类 是一个大范围 是一个模子 它约束了事务有哪些属性 但是不能约束具体的值 ...

  9. python学习之路网络编程篇(第四篇)

    python学习之路网络编程篇(第四篇) 内容待补充

随机推荐

  1. (转)iOS7界面设计规范(11) - UI基础 - 图标与图形

    不知别人如何,我自己来讲,平时很习惯很有动力去做的一些事,譬如博客吧,一旦生活中出现一些让自己很难受的状况,就很容易受到影响:像是,你平时所习惯的生活状态都是基于某种东西的,一旦这种东西崩塌,会影响到 ...

  2. c++11 线程:让你的多线程任务更轻松

      介绍 本文旨在帮助有经验的Win32程序员来了解c++ 11线程库及同步对象 和 Win32线程及同步对象之间的区别和相似之处. 在Win32中,所有的同步对象句柄(HANDLE)是全局句柄.它们 ...

  3. 从点亮一个LED开始,Cortex-A9裸机程序设计

    电路原理图: 如何点亮一个LED? 通过对原理图进行分析,我们能够发现给三极管的基极加上一个高点平时,三级管be结导通构成通路,此时二极管就点亮了.若要将LED熄灭只需取消高电平输出. 如何使三级管基 ...

  4. MySql查看表信息

    SELECT TABLE_NAME, TABLE_COMMENT -- 指定信息列 FROM `information_schema`.`tables` A WHERE A.`TABLE_SCHEMA ...

  5. (转)wcf client与webservice通信(-)只修改配置文件而改变服务端

    http://www.cnblogs.com/yiyisawa/archive/2008/12/16/1356191.html 问题: 假设有一个大型系统新版本使用wcf 作为服务端,生成wcf cl ...

  6. PHP 日期格式化 参数参考

    a - "am" 或是 "pm" A - "AM" 或是 "PM" d - 几日,二位数字,若不足二位则前面补零; 如: ...

  7. Light oj 1030 概率DP

    D - Discovering Gold Crawling in process... Crawling failed Time Limit:2000MS     Memory Limit:32768 ...

  8. n!mod p的求法

    我们假设p为素数,n!=a*pe,则我们需要求解a mod p和e. e是n!能够迭代整除p的次数,因此可以使用下面式子计算: n/p+n/p2+n/p3…… 我们只需要对pt≤n的t进行计算所以复杂 ...

  9. Qt中gb2312/GBK的URL编解码函数

    编码函数: QByteArray encodeURI(QString str) { QByteArray array; QTextCodec *codec=QTextCodec::codecForNa ...

  10. LeetCode-Divdend two Integers

    题目: Divide two integers without using multiplication, division and mod operator. 思路分析 二分法.将除数不断增倍,而结 ...