好冷的Python–tuple和逗号的恩怨情仇

原文链接:http://www.juzicode.com/archives/1499

《Python进阶教程m7b–混合编程–C语言接口ctypes(1)》中讲到封装C函数时的argstype ,以及在《Python进阶教程m10–多线程》 中讲到创建线程实例时传递函数入参args,如果参数只有一个时,这一个元素之后必须要增加一个逗号“,”,否则就会抛TypeError异常。

我们接下来看看为什么一定要加上这个显得多余的逗号,既然抛TypeError异常了,我们就用type()来看下它们的差异。

如果是一个不包含任何元素的”()”,其类型妥妥的是一个tuple :

>>> a = ()
>>> type(a)
<type 'tuple'>
>>>

当小括号内部仅有一个整数而没有添加逗号时,类型却是int:

>>> a = (1)
>>> type(a)
<type 'int'>
>>>

当小括号内部仅有一个整数且该整数后有逗号时,它的类型又变回了tuple:

>>> a = (1,)
>>> type(a)
<type 'tuple'>
>>>

这种形式上的不一致性就会导致我们在编写程序时,如果遇到只有一个元素的tuple,容易忘记加上逗号,从而导致程序抛异常。

再来看个例子,这段程序本意是要计算1,2,3 三个数值的和:

def add(x,y):
    return x+y,

print('微信公众号:桔子code')
a = 1
b = 2
c = 3
sum = add(a,b)
sum = sum + c
print('sum=',sum)    
==========运行结果:
微信公众号:桔子code
Traceback (most recent call last):
  File "E:\juzicode\pycold\tuple-test.py", line 9, in <module>
    sum = sum + c
TypeError: can only concatenate tuple (not "int") to tuple

运行文件居然抛异常了,提示“sum = sum + c” 这一行中有TypeError,意思是只能用tuple和tuple相加,不能用int和tuple相加。

what?

a和b相加是个int数据,再和c相加,这里明明是int和int相加,怎么提示是int和tuple相加, “sum = sum + c” 这一行中c是int无疑了,难道这里sum是个tuple?改下程序,打印add()函数的返回值sum的类型看看:

def add(x,y):
    return x+y,

print('微信公众号:桔子code')
a = 1
b = 2
c = 3
sum = add(a,b)
print('type of sum',type(sum))
sum = sum + c
print('sum=',sum)    
==========运行结果:
微信公众号:桔子code
type of sum <class 'tuple'>
Traceback (most recent call last):
  File "E:\juzicode\pycold\tuple-test.py", line 10, in <module>
    sum = sum + c
TypeError: can only concatenate tuple (not "int") to tuple

果不其然,add()返回值果然是个tuple,往回看func的return值,问题就在这里:“return x+y,” ,最后面多了个逗号“,”,我们知道函数return形式上可以返回多个值,多个值之间用逗号分隔,实际上返回的是个tuple。我们通常用“()”来定义tuple,但也可以不使用“()”,而是直接用多个逗号将各元素间隔的方式来定义一个tuple:

>>> a = 1,2,3
>>> type(a)
<type 'tuple'>
>>>
>>> a = 1,
>>> type(a)
<type 'tuple'>

从上面的例子可以看出如果这么定义变量:

a = 1,

实际上a是一个tuple。

回到前面挖的坑,“ return x+y, ” 实际上返回的是一个tuple,所以才导致了抛异常提示不能用int和tuple相加。

Python虽强大,使用需小心!一个不起眼的逗号该有的时候却没有,或者不该有的时候却出现了,都可能会浪费你很长的时间去“抓虫子”。

推荐阅读: 
好冷的Python–tuple和逗号的恩怨情仇 
好冷的Python–三引号注释,你的要求为什么这么多!
好冷的Python–源文件编码 
好冷的Python–pass和它的备胎们 

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注