python-socketio 文档翻译

Python015

python-socketio 文档翻译,第1张

教程: https://tutorialedge.net/python/python-socket-io-tutorial/

python-socketio 原文地址 ,在google浏览器中可以翻译为中文去使用。

首先要搞明白几个问题:

说明

1)第一种room是每一个单独的客户端都有的。(通过 session ID 可以找到)

2)第二种是应用程序自己创建的。

在下面这个方法中,如果省略掉room参数,将会自动发送给所有的连接了的客户端。

译文:

Python-socketio实现了一个Python Socket.IO 服务,这个服务可以单独运行也可以综合于一个web项目中。下面是一些它的特征:

什么是Socket.IO?

Socket.IO是一个基于事件的双向通讯的传输协议(一般是web浏览器),和一个服务端。原始的客户端和服务端组件实现是通过JavaScript写的。

入门指南

可以使用 pip 安装Socket.IO:

下面是一个使用 aiohttp 框架(只支持Python 3.5+)实现异步IO的 Socket.IO server 简单的例子:

下面是一个类似的例子,但是使用的Flask和Eventlet的例子,兼容Python2.7和3.3+:

客户端应用必须引入 socket.io-client 库(1.3.5版本以及以上,越高越好)。

每次客户端连接到服务器的连接事件处理程序调用sid(会话ID)分配给连接和WSGI环境字典。

每次客户端连接到服务端的 conenct 事件都是由sid(session ID)分配到连接和WSGI环境字典调用的。服务端可以检查身份认证或者其他的头部信息去决定是否这个客户端允许被连接。要想拒绝一个客户端的连接,这个处理器必须返回 False 。

当客户端发送发送一个事件给服务端,相应的事件处理器会被 sid 和这个信息调用,可以是单个或者多个参数。这个应用可以定义尽量多的如果被需要的可以被事件处理器关联的事件。一个事件可以通过一个名称简单定义。

当一个客户端连接中断了, disconnect 事件就被调用,允许应用去执行清理工作。

服务端

Socket.IO 服务端是 socketio.Server 类的实例,他们可以被一个WSGI适用应用程序使用 socketio.Middleware 去合并:

使用 socketio.Server.on() 方法来注册服务端的事件处理器:

对于异步服务端来说,事件处理器可以是常规方法,或者是协程:

聊天室

因为Socket.IO是一个双向的协议,服务端可以在任意时间发送消息给任意的连接到的客户端。为了让它方便去将客户端定位到组中,应用程序可以将客户端放入到聊天室中去,然后将消息定位到整个聊天室中。

当客户端第一次连接,他们是被分配到他们自己的聊天室中,这个聊天是是以session ID(sid 参数会传递给所有的事件处理器)命名的。应用可以通过 socketio.Server.enter_room() 和 socketio.Server.leave_room() 自由地去创建聊天室和管理客户端。客户端可以在尽量多的房间里,也可以根据需求尽量频繁地被拉入拉出聊天室。当他们的连接不在特别的时候,单独的聊天室将会分配给她它们,应用程序可以自由地增加和移除客户端从聊天室中,尽管它只要这样做就会失去定位独立客户端的能力。

socketio.Server.emit() 方法会获得一个事件名称,一个可能是 str , bytes , list , dict 或者 tuple 类型的消息载体。当发送一个 tuple ,在其中的元素必须是上面的其他类型。元组中的元素将会被传递给客户端的回调函数为多个参数。定位一个个人客户端,客户端的 sid 将会被给一个聊天室(假设这个应用没有修改这些初始的聊天室)。定位所有的连接的客户端们,这个聊天室参数将会被触发。

通常在聊天室中当广播一个消息到一个用户组的时候,发送者是否接受他自己的消息是可选的。 soicketio.Server.emit() 方法提供了一个可选的 skip_sid 参数去指定一个想在广播中跳过的客户端。

Response

当一个客户端发送一个事件给服务端,它可以选择提供一个回调方法,当服务端返回一个响应的时候会被触发。服务端可以便捷地从相应的事件处理器返回它从而提供一个响应。

事件处理器可以返回一个单独的值,一个带多个值的元组。这个在客户端的回调函数将会调用这些返回的值。

Callbacks

回调

服务端可以请求一个响应通过发送一个事件给客户端。 socketio.Server.emit() 方法有一个可选的 callback 参数能够被设置为可回调的。当这个参数被传递之后,当客户端返回相应的时候,这个可回调的方法将会被请求。

当广播给多个客户端的时候使用回调函数是不被推荐的,因为回调方法将会被只执行一次。

Namespace

命名空间

Socket.IO 协议支持多个逻辑性连接,所有的多路复用都是在相同的物理连接上。客户端可以通过给每个连接指定不同的 namespace 从而开多个连接。一个命名空间是由 主机名+端口+路径名称构成的。比如,连接到 http://example.com:8000/chat 将会开一个连接到命名空间 /chat 。

由于分离的不同的session ID( sid s),不同的事件处理器,不同的聊天室,每一个命名空间都是独立的。应用程序使用多个命名空间从而来区分命名空间,是非常重要的。可以参考 socketio.Server 类。

当 namespace 参数被触发了,比如设置为 None 或者 / , 那么一个默认的命名空间将会被使用。

Class-Based Namespaces

作为一个基于装饰器的事件处理器的代替,这个属于一个命名空间事件处理器可以被创建为 socketio.Namesapce 的子类:

对于基于异步io的服务端,域名空间必须继承与 socketio.AsyncNamespace , 也可以定义普通的方法或者协程作为事件处理器:

当使用基于类的命名空间的时候,任何被服务端接受的事件将会被分派到一个被事件名称命名的方法中作为方法名称(with the on_pfrefix )。比如:事件 my_event 将会被一个名叫 on_my_event 的方法处理。

17.1 subprocess

这个模块允许你产生子线程,连接他们(主线成,和产生的子线程)之间的输入/输出/错误 管道(pipes,管道是一种把两个进程之间的标准输入和标准输出连接起来的机制,从而提供一种让多个进程间通信的方法)。这个模块想要替换一些比较旧的模块和方法:

17.1.1 使用subprocess

在使用subprocess时推荐调用以下几个方来完成你的需求。如果有更高级的情况,可以使用Popen接口。

根据args参数运行命令,等待命令执行结束,返回进程返回值

根据args参数运行命令,等待命令执行结束,如果进程返回值为0则返回(return),否则会raise一个CalledProcessError错误,CalledProcessError类的returncode属性会包含进程返回值。

subprocess.check_output( args , * , stdin=None , stderr=None , shell=False , universal_newlines=False )

正在更新....

Python中有许多内置函数,不像print、len那么广为人知,但它们的功能却异常强大,用好了可以大大提高代码效率,同时提升代码的简洁度,增强可阅读性

Counter

collections在python官方文档中的解释是High-performance container datatypes,直接的中文翻译解释高性能容量数据类型。这个模块实现了特定目标的容器,以提供Python标准内建容器 dict , list , set , 和 tuple 的替代选择。在python3.10.1中它总共包含以下几种数据类型:

容器名简介

namedtuple() 创建命名元组子类的工厂函数

deque 类似列表(list)的容器,实现了在两端快速添加(append)和弹出(pop)

ChainMap 类似字典(dict)的容器类,将多个映射集合到一个视图里面

Counter 字典的子类,提供了可哈希对象的计数功能

OrderedDict 字典的子类,保存了他们被添加的顺序

defaultdict 字典的子类,提供了一个工厂函数,为字典查询提供一个默认值

UserDict 封装了字典对象,简化了字典子类化

UserList 封装了列表对象,简化了列表子类化

UserString 封装了字符串对象,简化了字符串子类化

其中Counter中文意思是计数器,也就是我们常用于统计的一种数据类型,在使用Counter之后可以让我们的代码更加简单易读。Counter类继承dict类,所以它能使用dict类里面的方法

举例

#统计词频

fruits = ['apple', 'peach', 'apple', 'lemon', 'peach', 'peach']

result = {}

for fruit in fruits:

if not result.get(fruit):

result[fruit] = 1

else:

result[fruit] += 1

print(result)

#{'apple': 2, 'peach': 3, 'lemon': 1}下面我们看用Counter怎么实现:

from collections import Counter

fruits = ['apple', 'peach', 'apple', 'lemon', 'peach', 'peach']

c = Counter(fruits)

print(dict(c))

#{'apple': 2, 'peach': 3, 'lemon': 1}显然代码更加简单了,也更容易阅读和维护了。

elements()

返回一个迭代器,其中每个元素将重复出现计数值所指定次。元素会按首次出现的顺序返回。如果一个元素的计数值小于1,elements()将会忽略它。

>>>c = Counter(a=4, b=2, c=0, d=-2)

>>>sorted(c.elements())

['a', 'a', 'a', 'a', 'b', 'b']most_common([n])

返回一个列表,其中包含n个最常见的元素及出现次数,按常见程度由高到低排序。如果n被省略或为None,most_common()将返回计数器中的所有元素。计数值相等的元素按首次出现的顺序排序:

>>>Counter('abracadabra').most_common(3)

[('a', 5), ('b', 2), ('r', 2)]这两个方法是Counter中最常用的方法,其他方法可以参考 python3.10.1官方文档

实战

Leetcode 1002.查找共用字符

给你一个字符串数组words,请你找出所有在words的每个字符串中都出现的共用字符(包括重复字符),并以数组形式返回。你可以按任意顺序返回答案。

输入:words = ["bella", "label", "roller"]

输出:["e", "l", "l"]

输入:words = ["cool", "lock", "cook"]

输出:["c", "o"]看到统计字符,典型的可以用Counter完美解决。这道题是找出字符串列表里面每个元素都包含的字符,首先可以用Counter计算出每个元素每个字符出现的次数,依次取交集最后得出所有元素共同存在的字符,然后利用elements输出共用字符出现的次数

class Solution:

def commonChars(self, words: List[str]) ->List[str]:

from collections import Counter

ans = Counter(words[0])

for i in words[1:]:

ans &= Counter(i)

return list(ans.elements())提交一下,发现83个测试用例耗时48ms,速度还是不错的

sorted

在处理数据过程中,我们经常会用到排序操作,比如将列表、字典、元组里面的元素正/倒排序。这时候就需要用到sorted(),它可以对任何可迭代对象进行排序,并返回列表

对列表升序操作:

a = sorted([2, 4, 3, 7, 1, 9])

print(a)

# 输出:[1, 2, 3, 4, 7, 9]对元组倒序操作:

sorted((4,1,9,6),reverse=True)

print(a)

# 输出:[9, 6, 4, 1]使用参数:key,根据自定义规则,按字符串长度来排序:

fruits = ['apple', 'watermelon', 'pear', 'banana']

a = sorted(fruits, key = lambda x : len(x))

print(a)

# 输出:['pear', 'apple', 'banana', 'watermelon']all

all() 函数用于判断给定的可迭代参数iterable中的所有元素是否都为 TRUE,如果是返回 True,否则返回 False。元素除了是 0、空、None、False外都算True。注意:空元组、空列表返回值为True。

>>>all(['a', 'b', 'c', 'd']) # 列表list,元素都不为空或0

True

>>>all(['a', 'b', '', 'd']) # 列表list,存在一个为空的元素

False

>>>all([0, 1,2, 3]) # 列表list,存在一个为0的元素

False

>>>all(('a', 'b', 'c', 'd')) # 元组tuple,元素都不为空或0

True

>>>all(('a', 'b', '', 'd')) # 元组tuple,存在一个为空的元素

False

>>>all((0, 1, 2, 3)) # 元组tuple,存在一个为0的元素

False

>>>all([]) # 空列表

True

>>>all(()) # 空元组

Trueany函数正好和all函数相反:判断一个tuple或者list是否全为空,0,False。如果全为空,0,False,则返回False;如果不全为空,则返回True。

F-strings

在python3.6.2版本中,PEP 498提出一种新型字符串格式化机制,被称为 “字符串插值” 或者更常见的一种称呼是F-strings,F-strings提供了一种明确且方便的方式将python表达式嵌入到字符串中来进行格式化:

s1='Hello'

s2='World'

print(f'{s1} {s2}!')

# Hello World!在F-strings中我们也可以执行函数:

def power(x):

return x*x

x=4

print(f'{x} * {x} = {power(x)}')

# 4 * 4 = 16而且F-strings的运行速度很快,比传统的%-string和str.format()这两种格式化方法都快得多,书写起来也更加简单。

本文主要讲解了python几种冷门但好用的函数,更多内容以后会陆陆续续更新~