为啥我们必须在 python 多线程的 args 中添加逗号','?
Posted
技术标签:
【中文标题】为啥我们必须在 python 多线程的 args 中添加逗号\',\'?【英文标题】:Why do we have to add comma ',' in args in python multithreading?为什么我们必须在 python 多线程的 args 中添加逗号','? 【发布时间】:2021-12-19 20:17:33 【问题描述】:我是 python 新手,我不知道为什么我们在 args 中使用逗号 ',' 来表示 Thread 例如:
import threading
import time
semaphore = threading.BoundedSemaphore(value=5)
def access(thread_number):
print(": Trying access...".format(thread_number))
semaphore.acquire()
print(": Access granted!".format(thread_number))
print(": waiting 5 seconds...".format(thread_number))
time.sleep(5)
semaphore.release()
print(": Releasing!...".format(thread_number))
for thread_number in range(10):
t = threading.Thread(target=access, args=(thread_number,))
t.start()
为什么有效? "args = (thread_number,)" 怎么用逗号结尾?
【问题讨论】:
逗号定义了args
期望的元组。
那么即使我们只有一个变量,这也需要吗?
是的,因为(x)
不是元组,而(x,)
是。除了空元组()
,元组总是由逗号定义,而不是由括号定义。括号仅在此处用于消除元组逗号与虚构参数列表逗号的歧义。
好的,这清除了逗号的原因,谢谢! @chepner
【参考方案1】:
如果你添加逗号,那么对于 python 它是一个元组,空括号也是一个元组
>>> type( (1,) )
<class 'tuple'>
>>> type( (1) )
<class 'int'>
>>> type( (1,2))
<class 'tuple'>
>>> type( () )
<class 'tuple'>
【讨论】:
【参考方案2】:唉,这并不是特别容易——它处于 Python 语法的一些黑暗角落的交汇处。
首先,需要逗号来组成一个元组,一个元素,包含线程号:
>>> 6
6
>>> 6,
(6,)
>>> (6,)
(6,)
>>> (6)
6
看到了吗?如果没有逗号,或者只有 括号,6 就是 int 6。但是如果有逗号 - 无论有没有括号 - 它都会变成一个包含 int 6 作为其唯一元素的元组。
为什么它需要是一个元组?您很快就会被告知它实际上没有 ;-) ,但在此之前请考虑您可能需要将任意数量的参数传递给线程。所以args=
之后的表达式必须产生一个序列。
但是如果逗号的出现构成一个元组,为什么还需要括号呢?那是“一些黑暗角落的交集”:参数列表中的逗号 also 分隔参数,并且在这种情况下优先。所以需要括号来强制执行意图:“这个逗号并不意味着下一个参数正在开始 - 这个逗号意味着我想要一个元组”。
为避免考虑所有这些,您可以在此上下文中使用列表作为序列:
t = threading.Thread(target=access, args=[thread_number])
Thread
的实现并不关心作为args=
的值传递的序列类型,许多代码实际上使用列表而不是元组。但是,上次看的时候,还没有记录,所以有点冒险。
编辑
我因为added a request to the Python issue tracker 要求我们最终记录一个列表在这种情况下是好的。一直都是。看起来几乎可以肯定会进行此文档更改。
【讨论】:
非常感谢您的解释!这就像所有问题一样清除。 很高兴它有帮助!为了鼓励起见,我要说一个强有力的例子,即 Python 的单元素元组语法可能是该语言中最丑陋的(令人惊讶的,...,weird)语法。所以不要害怕每天都会遇到“像这样”的新事物 ;-)以上是关于为啥我们必须在 python 多线程的 args 中添加逗号','?的主要内容,如果未能解决你的问题,请参考以下文章