㈠ linux python connect 对同一个端口可以建立多少个
如果是tcp client用同一个本地端口去连不同的两个服务器ip,连第二个时就会提示端口已被占用。但服务器的监听端口,可以accept多次,建立多个socket;我的问题是服务器一个端口为什么能建立多个连败樱接而客户端却不行呢?
TCP server 可以,TCP client 也可以。一个套接字只能建立一个连接,无论对于 server 还是 client。
注意报错消息是:
[Errno 106] (EISCONN) Transport endpoint is already connected
man 2 connect 说得很清楚了:
Generally, connection-based protocol sockets may successfully connect() only once; connectionless protocol sockets may use connect() multiple times to change their association.
就是说,TCP 套接字最多只能调用 connect 一次。那么,你的监听套接字调用 connect 了几次?
来点有意思的。
一个套接字不能连接两次,并不代表一个本地地址不能用两次,看!****加粗文字**加做并粗文字**
>>> import socket
>>> s = socket.socket()
# since Linux 3.9, 见 man 7 socket
>>> s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
>>> s2 = socket.socket()
>>> s2.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
>>> s.bind(('127.0.0.1', 12345))
>>> s2.bind(('127.0.0.1', 12345))
# 都可以使用同一本地地址来连接哦
>>> s.connect(('127.0.0.1', 80))
>>> s2.connect(('127.0.0.1', 4321))
>>> netstat -npt | grep 12345
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 127.0.0.1:4321 127.0.0.1:12345 ESTABLISHED 18284/python3
tcp 0 0 127.0.0.1:12345 127.0.0.1:4321 ESTABLISHED 4568/python3
tcp 0 0 127.0.0.1:80 127.0.0.1:12345 ESTABLISHED -
tcp 0 0 127.0.0.1:12345 127.0.0.1:80 ESTABLISHED 4568/python3
你们这些有女友的都弱爆了啦 :-(
更新:大家来玩 TCP: 一个人也可以建立 TCP 连接呢 - 依云's Blog
2015年08月19日回答 · 2015年08月19日更新
依云21.1k 声望
答案对人有帮助,有参考价值1答案没帮助,是错误的答案,答非所问
内核是以一个(着名的)5元信息组来标识不同的socket的:源地址、源端口、目的地址、目的端口、协议号。任何一个不同,都不叫“同一个socket”。
2015年08月20日回答
sched_yield80 声望
答案对人有帮察胡丛助,有参考价值0答案没帮助,是错误的答案,答非所问
首先,TCP链接是可靠的端对端的链接,每个TCP链接由4个要素组成:2组IP地址(本地和远端),2组端口地址(本地和远端)。其中如果需要跟端口信息绑定时,都需要调用bind函数,如果server端针对2个同样的IP、端口组进行同样的绑定时,第2次同样是不成功的。
2015年08月16日回答
charliecui2.4k 声望
答案对人有帮助,有参考价值0答案没帮助,是错误的答案,答非所问
有个相关的问题: ftp的数据传输,服务器会用20端口主动连接客户端,如果两个客户端同时在一下载东西,那ftp 服务器能用20端口去连接两个ip ?(这时ftp的服务器其实是tcp里的客户端)
2015年08月16日回答
编辑
hyanleo163 声望
+1
能啊,看我的实验。
依云 · 2015年08月19日
不管是服务器还是客户端,建立TCP链接,同一个端口都只能使用一次。
这句话其实是**错的**!
对于TCP协议,要成功建立一个新的链接,需要保证新链接四个要素组合体的唯一性:客户端的IP、客户端的port、服务器端的IP、服务器端的port。也就是说,服务器端的同一个IP和port,可以和同一个客户端的多个不同端口成功建立多个TCP链接(与多个不同的客户端当然也可以),只要保证【Server IP + Server Port + Client IP + Client Port】这个组合唯一不重复即可。
> netstat -a -n -p tcp |grep 9999
tcp 0 0 127.0.0.1:51113 127.0.0.1:9999 ESTABLISHED 2701/nc
tcp 0 0 127.0.0.1:51119 127.0.0.1:9999 ESTABLISHED 2752/nc
上述结果127.0.0.1:9999中9999端口成功建立两个TCP链接,也就可以理解。
**客户端**发送TCP链接请求的端口,也就是后续建立TCP链接使用的端口,所以一旦TCP链接建立,端口就被占用,无法再建立第二个链接。
而**服务器端**有两类端口:侦听端口 和 后续建立TCP链接的端口。其中侦听端口只负责侦听客户端发送来的TCP链接请求,不用作建立TCP链接使用,一旦侦听到有客户端发送TCP链接请求,就分配一个端口(一般随机分配,且不会重复)用于建立TCP链接,而不是所说的服务器一个端口能建立多个连接。
上述描述也比较片面,客户端如何请求及建立链接,服务器端如何侦听及是否分配新随机端口等...应该都可以在应用层面进行控制,所以上述描述可以作为建立TCP链接的一种方式,仅供参考。
一些英文的参考:
How do multiple clients connect simultaneously to one port, say 80, on a server?
TCP : two different sockets sharing a port?
------------------------------------------------------------------------------------
提升linux下tcp服务器并发连接数限制 2012-12-02 20:30:23
1、修改用户进程可打开文件数限制
在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统为每个TCP连接都要创建一个socket句柄,每个socket句柄同时也是一个文件句柄)。可使用ulimit命令查看系统允许当前用户进程打开的文件数限制:
[speng@as4 ~]$ ulimit -n
1024
这表示当前用户的每个进程最多允许同时打开1024个文件,这1024个文件中还得除去每个进程必然打开的标准输入,标准输出,标准错误,服务器监听 socket,进程间通讯的unix域socket等文件,那么剩下的可用于客户端socket连接的文件数就只有大概1024-10=1014个左右。也就是说缺省情况下,基于Linux的通讯程序最多允许同时1014个TCP并发连接。
对于想支持更高数量的TCP并发连接的通讯处理程序,就必须修改Linux对当前用户的进程同时打开的文件数量的软限制(soft limit)和硬限制(hardlimit)。其中软限制是指Linux在当前系统能够承受的范围内进一步限制用户同时打开的文件数;硬限制则是根据系统硬件资源状况(主要是系统内存)计算出来的系统最多可同时打开的文件数量。通常软限制小于或等于硬限制。
修改上述限制的最简单的办法就是使用ulimit命令:
[speng@as4 ~]$ ulimit -n
上述命令中,在中指定要设置的单一进程允许打开的最大文件数。如果系统回显类似于“Operation notpermitted”之类的话,说明上述限制修改失败,实际上是因为在中指定的数值超过了Linux系统对该用户打开文件数的软限制或硬限制。因此,就需要修改Linux系统对用户的关于打开文件数的软限制和硬限制。
第一步,修改/etc/security/limits.conf文件,在文件中添加如下行:
speng soft nofile 10240
speng hard nofile 10240
其中speng指定了要修改哪个用户的打开文件数限制,可用'*'号表示修改所有用户的限制;soft或hard指定要修改软限制还是硬限制;10240则指定了想要修改的新的限制值,即最大打开文件数(请注意软限制值要小于或等于硬限制)。修改完后保存文件。
第二步,修改/etc/pam.d/login文件,在文件中添加如下行:
session required /lib/security/pam_limits.so
这是告诉Linux在用户完成系统登录后,应该调用pam_limits.so模块来设置系统对该用户可使用的各种资源数量的最大限制(包括用户可打开的最大文件数限制),而pam_limits.so模块就会从/etc/security/limits.conf文件中读取配置来设置这些限制值。修改完后保存此文件。
第三步,查看Linux系统级的最大打开文件数限制,使用如下命令:
[speng@as4 ~]$ cat /proc/sys/fs/file-max
12158
这表明这台Linux系统最多允许同时打开(即包含所有用户打开文件数总和)12158个文件,是Linux系统级硬限制,所有用户级的打开文件数限制都不应超过这个数值。通常这个系统级硬限制是Linux系统在启动时根据系统硬件资源状况计算出来的最佳的最大同时打开文件数限制,如果没有特殊需要,不应该修改此限制,除非想为用户级打开文件数限制设置超过此限制的值。修改此硬限制的方法是修改/etc/rc.local脚本,在脚本中添加如下行:
echo 22158 > /proc/sys/fs/file-max
这是让Linux在启动完成后强行将系统级打开文件数硬限制设置为22158。修改完后保存此文件。
完成上述步骤后重启系统,一般情况下就可以将Linux系统对指定用户的单一进程允许同时打开的最大文件数限制设为指定的数值。如果重启后用 ulimit- n命令查看用户可打开文件数限制仍然低于上述步骤中设置的最大值,这可能是因为在用户登录脚本/etc/profile中使用ulimit-n命令已经将用户可同时打开的文件数做了限制。由于通过ulimit-n修改系统对用户可同时打开文件的最大数限制时,新修改的值只能小于或等于上次ulimit-n 设置的值,因此想用此命令增大这个限制值是不可能的。所以,如果有上述问题存在,就只能去打开/etc/profile脚本文件,在文件中查找是否使用了 ulimit-n限制了用户可同时打开的最大文件数量,如果找到,则删除这行命令,或者将其设置的值改为合适的值,然后保存文件,用户退出并重新登录系统即可。
通过上述步骤,就为支持高并发TCP连接处理的通讯处理程序解除关于打开文件数量方面的系统限制。
2、修改网络内核对TCP连接的有关限制
在Linux上编写支持高并发TCP连接的客户端通讯处理程序时,有时会发现尽管已经解除了系统对用户同时打开文件数的限制,但仍会出现并发TCP连接数增加到一定数量时,再也无法成功建立新的TCP连接的现象。出现这种现在的原因有多种。
第一种原因可能是因为Linux网络内核对本地端口号范围有限制。此时,进一步分析为什么无法建立TCP连接,会发现问题出在connect()调用返回失败,查看系统错误提示消息是“Can't assign requestedaddress”。同时,如果在此时用tcpmp工具监视网络,会发现根本没有TCP连接时客户端发SYN包的网络流量。这些情况说明问题在于本地Linux系统内核中有限制。其实,问题的根本原因在于Linux内核的TCP/IP协议实现模块对系统中所有的客户端TCP连接对应的本地端口号的范围进行了限制(例如,内核限制本地端口号的范围为1024~32768之间)。当系统中某一时刻同时存在太多的TCP客户端连接时,由于每个TCP客户端连接都要占用一个唯一的本地端口号(此端口号在系统的本地端口号范围限制中),如果现有的TCP客户端连接已将所有的本地端口号占满,则此时就无法为新的TCP客户端连接分配一个本地端口号了,因此系统会在这种情况下在connect()调用中返回失败,并将错误提示消息设为“Can't assignrequested address”。有关这些控制逻辑可以查看Linux内核源代码,以linux2.6内核为例,可以查看tcp_ipv4.c文件中如下函数:
static int tcp_v4_hash_connect(struct sock *sk)
请注意上述函数中对变量sysctl_local_port_range的访问控制。变量sysctl_local_port_range的初始化则是在tcp.c文件中的如下函数中设置:
void __init tcp_init(void)
内核编译时默认设置的本地端口号范围可能太小,因此需要修改此本地端口范围限制。
第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:
net.ipv4.ip_local_port_range = 1024 65000
这表明将系统对本地端口范围限制设置为1024~65000之间。请注意,本地端口范围的最小值必须大于或等于1024;而端口范围的最大值则应小于或等于65535。修改完后保存此文件。
第二步,执行sysctl命令:
[speng@as4 ~]$ sysctl -p
如果系统没有错误提示,就表明新的本地端口范围设置成功。如果按上述端口范围进行设置,则理论上单独一个进程最多可以同时建立60000多个TCP客户端连接。
第二种无法建立TCP连接的原因可能是因为Linux网络内核的IP_TABLE防火墙对最大跟踪的TCP连接数有限制。此时程序会表现为在 connect()调用中阻塞,如同死机,如果用tcpmp工具监视网络,也会发现根本没有TCP连接时客户端发SYN包的网络流量。由于 IP_TABLE防火墙在内核中会对每个TCP连接的状态进行跟踪,跟踪信息将会放在位于内核内存中的conntrackdatabase中,这个数据库的大小有限,当系统中存在过多的TCP连接时,数据库容量不足,IP_TABLE无法为新的TCP连接建立跟踪信息,于是表现为在connect()调用中阻塞。此时就必须修改内核对最大跟踪的TCP连接数的限制,方法同修改内核对本地端口号范围的限制是类似的:
第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:
net.ipv4.ip_conntrack_max = 10240
这表明将系统对最大跟踪的TCP连接数限制设置为10240。请注意,此限制值要尽量小,以节省对内核内存的占用。
第二步,执行sysctl命令:
[speng@as4 ~]$ sysctl -p
如果系统没有错误提示,就表明系统对新的最大跟踪的TCP连接数限制修改成功。如果按上述参数进行设置,则理论上单独一个进程最多可以同时建立10000多个TCP客户端连接。
3、使用支持高并发网络I/O的编程技术
在Linux上编写高并发TCP连接应用程序时,必须使用合适的网络I/O技术和I/O事件分派机制。
可用的I/O技术有同步I/O,非阻塞式同步I/O(也称反应式I/O),以及异步I/O。在高TCP并发的情形下,如果使用同步I/O,这会严重阻塞程序的运转,除非为每个TCP连接的I/O创建一个线程。但是,过多的线程又会因系统对线程的调度造成巨大开销。因此,在高TCP并发的情形下使用同步I /O 是不可取的,这时可以考虑使用非阻塞式同步I/O或异步I/O。非阻塞式同步I/O的技术包括使用select(),poll(),epoll等机制。异步I/O的技术就是使用AIO。
从I/O事件分派机制来看,使用select()是不合适的,因为它所支持的并发连接数有限(通常在1024个以内)。如果考虑性能,poll()也是不合适的,尽管它可以支持的较高的TCP并发数,但是由于其采用“轮询”机制,当并发数较高时,其运行效率相当低,并可能存在I/O事件分派不均,导致部分 TCP连接上的I/O出现“饥饿”现象。而如果使用epoll或AIO,则没有上述问题(早期 Linux内核的AIO技术实现是通过在内核中为每个I/O请求创建一个线程来实现的,这种实现机制在高并发TCP连接的情形下使用其实也有严重的性能问题。但在最新的Linux内核中,AIO的实现已经得到改进)。
综上所述,在开发支持高并发TCP连接的Linux应用程序时,应尽量使用epoll或AIO技术来实现并发的TCP连接上的I/O控制,这将为提升程序对高并发TCP连接的支持提供有效的I/O保证。
㈡ Python如何进行多串口通信一个串口控制电机 一个串口采集数据
下载 pyserial包
def OpenCom(self,*args): #设置端口和波特率 selComPort =‘com2’ #波特率 selBaudRate =9600 #奇偶校验 selParity = 'N' try: if(not self.mySerial): self.mySerial = serial.Serial(port=selComPort, baudrate=selBaudRate,bytesize=8,parity=selParity,stopbits=1,timeout=5) else: if(self.mySerial.isOpen()): self.mySerial.close() self.mySerial = serial.Serial(port=selComPort, baudrate=selBaudRate, bytesize=8, parity=selParity, stopbits=1, timeout=5) self.lblInfo['text'] = '打开成功!' except Exception as ex: self.lblInfo['text'] = '打开失败!'
#使用com口发送modbus协议给终端设备。
def btnEmId_Click(self):
barray = bytearray([0x05, 0x03, 0xA#, 0x54, 0x00, 0x08])
vOldEmId = self.txbOldEmId.get()
vNewEmId = self.txbNewEmId.get()
barray[0] = int(vOldEmId)
barray[5] = int(vNewEmId)
#crc校验
strInput = utils.crc16_append(barray)
print(barray)
n = self.mySerial.write(barray)
if(n > 0):
str = self.mySerial.readall()
self.lblInfo['text'] = 'success!'
# for s in str:
# print (hex(s))
else:
self.lblInfo['text'] = 'error!'
㈢ pandas python 怎么删除表格中的某一行
某列中所有的数据都是1,加起来不就是总行数吗?引言本文的目的,是向您展示如何使用pandas来执行一些常见的Excel任务。有些例子比较琐碎,但我觉得展示这些简单的东西与那些你可以在其他地方找到的复杂功能同等重要。作为额外的福利,我将会进行一些模糊字符串匹配,以此来展示一些小花样,以及展示pandas是如何利用完整的Python模块系统去做一些在Python中是简单,但在Excel中却很复杂的事情的。有道理吧?让我们开始吧。为某行添加求和项我要介绍的第一项任务是把某几列相加然后添加一个总和栏。首先我们将excel数据导入到pandas数据框架中。=pd.read_excel("excel-comp-data.xlsx")df.head()我们想要添加一个总和栏来显示Jan、Feb和Mar三个月的销售总额。在Excel和pandas中这都是简单直接的。对于Excel,我在J列中添加了公式sum(G2:I2)。在Excel中看上去是这样的:下面,我们是这样在pandas中操作的:df["total"]=df["Jan"]+df["Feb"]+df["Mar"]df.head()接下来,让我们对各列计算一些汇总信息以及其他值。如下Excel表所示,我们要做这些工作:如你所见,我们在表示月份的列的第17行添加了SUM(G2:G16),来取得每月的总和。进行在pandas中进行列级别的分析很简单。下面是一些例子:df["Jan"].sum(),df["Jan"].mean(),df["Jan"].min(),df["Jan"].max()(1462000,97466.666666666672,10000,162000)现在我们要把每月的总和相加得到它们的和。这里pandas和Excel有点不同。在Excel的单元格里把每个月的总和相加很简单。由于pandas需要维护整个DataFrame的完整性,所以需要一些额外的步骤。首先,建立所有列的总和栏sum_row=df[["Jan","Feb","Mar","total"]].sum()sum_:int64这很符合直觉,不过如果你希望将总和值显示为表格中的单独一行,你还需要做一些微调。我们需要把数据进行变换,把这一系列数字转换为DataFrame,这样才能更加容易的把它合并进已经存在的数据中。T函数可以让我们把按行排列的数据变换为按列排列。df_sum=pd.DataFrame(data=sum_row).Tdf_sum在计算总和之前我们要做的最后一件事情是添加丢失的列。我们使用reindex来帮助我们完成。技巧是添加全部的列然后让pandas去添加所有缺失的数据。df_sum=df_sum.reindex(columns=df.columns)df_sum现在我们已经有了一个格式良好的DataFrame,我们可以使用append来把它加入到已有的内容中。df_final=df.append(df_sum,ignore_index=True)df_final.tail()额外的数据变换另外一个例子,让我们尝试给数据集添加状态的缩写。对于Excel,最简单的方式是添加一个新的列,对州名使用vlookup函数并填充缩写栏。我进行了这样的操作,下面是其结果的截图:你可以注意到,在进行了vlookup后,有一些数值并没有被正确的取得。这是因为我们拼错了一些州的名字。在Excel中处理这一问题是一个巨大的挑战(对于大型数据集而言)幸运的是,使用pandas我们可以利用强大的python生态系统。考虑如何解决这类麻烦的数据问题,我考虑进行一些模糊文本匹配来决定正确的值。幸运的是其他人已经做了很多这方面的工作。fuzzywuzzy库包含一些非常有用的函数来解决这类问题。首先要确保你安装了他。我们需要的另外一段代码是州名与其缩写的映射表。而不是亲自去输入它们,谷歌一下你就能找到这段代码code。首先导入合适的fuzzywuzzy函数并且定义我们的州名映射表。_to_code={"VERMONT":"VT","GEORGIA":"GA","IOWA":"IA","ArmedForcesPacific":"AP","GUAM":"GU","KANSAS":"KS","FLORIDA":"FL","AMERICANSAMOA":"AS","NORTHCAROLINA":"NC","HAWAII":"HI","NEWYORK":"NY","CALIFORNIA":"CA","ALABAMA":"AL","IDAHO":"ID","FEDERATEDSTATESOFMICRONESIA":"FM","ArmedForcesAmericas":"AA","DELAWARE":"DE","ALASKA":"AK","ILLINOIS":"IL","ArmedForcesAfrica":"AE","SOUTHDAKOTA":"SD","CONNECTICUT":"CT","MONTANA":"MT","MASSACHUSETTS":"MA","PUERTORICO":"PR","ArmedForcesCanada":"AE","NEWHAMPSHIRE":"NH","MARYLAND":"MD","NEWMEXICO":"NM","MISSISSIPPI":"MS","TENNESSEE":"TN","PALAU":"PW","COLORADO":"CO","ArmedForcesMiddleEast":"AE","NEWJERSEY":"NJ","UTAH":"UT","MICHIGAN":"MI","WESTVIRGINIA":"WV","WASHINGTON":"WA","MINNESOTA":"MN","OREGON":"OR","VIRGINIA":"VA","VIRGINISLANDS":"VI","MARSHALLISLANDS":"MH","WYOMING":"WY","OHIO":"OH","SOUTHCAROLINA":"SC","INDIANA":"IN","NEVADA":"NV","LOUISIANA":"LA","NORTHERNMARIANAISLANDS":"MP","NEBRASKA":"NE","ARIZONA":"AZ","WISCONSIN":"WI","NORTHDAKOTA":"ND","ArmedForcesEurope":"AE","PENNSYLVANIA":"PA","OKLAHOMA":"OK","KENTUCKY":"KY","RHODEISLAND":"RI","DISTRICTOFCOLUMBIA":"DC","ARKANSAS":"AR","MISSOURI":"MO","TEXAS":"TX","MAINE":"ME"}这里有些介绍模糊文本匹配函数如何工作的例子。process.extractOne("Minnesotta",choices=state_to_code.keys())('MINNESOTA',95)process.extractOne("AlaBAMMazzz",choices=state_to_code.keys(),score_cutoff=80)现在我知道它是如何工作的了,我们创建自己的函数来接受州名这一列的数据然后把他转换为一个有效的缩写。这里我们使用score_cutoff的值为80。你可以做一些调整,看看哪个值对你的数据来说比较好。你会注意到,返回值要么是一个有效的缩写,要么是一个np.nan所以域中会有一些有效的值。defconvert_state(row):abbrev=process.extractOne(row["state"],choices=state_to_code.keys(),score_cutoff=80)ifabbrev:returnstate_to_code[abbrev[0]]returnnp.nan把这列添加到我们想要填充的单元格,然后用NaN填充它df_final.insert(6,"abbrev",np.nan)df_final.head()我们使用apply来把缩写添加到合适的列中。df_final['abbrev']=df_final.apply(convert_state,axis=1)df_final.tail()我觉的这很酷。我们已经开发出了一个非常简单的流程来智能的清理数据。显然,当你只有15行左右数据的时候这没什么了不起的。但是如果是15000行呢?在Excel中你就必须进行一些人工清理了。分类汇总在本文的最后一节中,让我们按州来做一些分类汇总(subtotal)。在Excel中,我们会用subtotal工具来完成。输出如下:在pandas中创建分类汇总,是使用groupby来完成的。df_sub=df_final[["abbrev","Jan","Feb","Mar","total"]].groupby('abbrev').sum()df_sub然后,我们想要通过对dataframe中所有的值使用applymap来把数据单位格式化为货币。defmoney(x):return"${:,.0f}".format(x)formatted_df=df_sub.applymap(money)formatted_df格式化看上去进行的很顺利,现在我们可以像之前那样获取总和了。sum_row=df_sub[["Jan","Feb","Mar","total"]].sum()sum_:int64把值变换为列然后进行格式化。df_sub_sum=pd.DataFrame(data=sum_row).Tdf_sub_sum=df_sub_sum.applymap(money)df_sub_sum最后,把总和添加到DataFrame中。final_table=formatted_df.append(df_sub_sum)final_table你可以注意到总和行的索引号是‘0'。我们想要使用rename来重命名它。final_table=final_table.rename(index={0:"Total"})final_table结论到目前为止,大部分人都已经知道使用pandas可以对数据做很多复杂的操作——就如同Excel一样。因为我一直在学习pandas,但我发现我还是会尝试记忆我是如何在Excel中完成这些操作的而不是在pandas中。我意识到把它俩作对比似乎不是很公平——它们是完全不同的工具。但是,我希望能接触到哪些了解Excel并且想要学习一些可以满足分析他们数据需求的其他替代工具的那些人。我希望这些例子可以帮助到其他人,让他们有信心认为他们可以使用pandas来替换他们零碎复杂的Excel,进行数据操作。
㈣ python模块smtplib怎么安装
python模块smtplib安装方法如下,根据你的需要选择执行:
[root@localhost ~]# pip search smtplib
PyEmail (0.0.1) - Python library to send emails using SMTPLIB library
micropython-smtplib (0.0.0) - Dummy smtplib mole for MicroPython
personal (0.1.1) - Easy, secure self notification via email and sms, using smtplib and twilio
aiosmtplib (0.1.4) - asyncio version of smtplib
secure-smtplib (0.1.1) - Secure SMTP subclasses for Python 2
mailclient (0.2.0) - Simplified use of smtplib for Python. Easy email sending.
smtplio (1.0.3) - An async version of smtplib
easyemail (0.4.0) - Simple lib abstracting email sending with smtplib.
㈤ python如何打开带变量名的txt文件并写入数据
python打开带变量名的txt文件的方法:
1、将txt文件名赋值给变量
2、使用“%s”可以将变量名传递到文件路径中,然后使用open()函数打开这个txt文件,用write()函数就可以写入数据了
完整代码如下:
执行结果如下:
更多Python知识,请关注:Python自学网!!