如何知道变量是元组,字符串还是整数?


77

我正在尝试在串联操作中将字符串添加到另一个字符串时找出类型不匹配的情况。

基本上,返回的错误是TypeError(无法连接字符串和元组);所以我想弄清楚我在哪里分配一个值作为元组而不是字符串。

我分配的所有值都是字符串,因此我必须弄清楚元组的来源,因此我希望Python中有一种方法可以找出变量中包含的内容以及变量的类型。

到目前为止,使用pdb可以检查变量的内容,并且可以正确地获得期望的值。但我也想知道变量的类型(通过逻辑,如果编译器能够引发类型错误,则意味着它知道变量内部的内容以及它是否与要执行的操作兼容;因此必须是一种获取该值/标记的方法)。

有什么办法可以打印出python中变量的类型?

顺便说一句,我试图将所有变量都更改为显式字符串,但是强制执行是不可行的str (myvar),因此我不能仅在使用字符串的任何地方都将其转换为字符串类型。

python 

2
不想挑剔,但是变量在Python中从来没有类型,只有对象(由变量引用)才有。因此,没有实类型转换,只有对象转换函数。
尔根·斯特罗贝尔

的确是于尔根;我不完全了解python的工作原理,但我认为这是一种面向对象的语言,因此当我创建变量时,它将创建正确数据类型的对象并使用指针对其进行引用,因此当我使用变量,我实际上使用的是对象字符串(或任何其他数据类型)的实例。您的终点是获取该对象的类型:)

Answers:


40

您只需使用:

type(varname)

这将输出int,str,float等。


使用__class__几乎总是比使用更好,type因为在大多数情况下,它们将返回相同的东西,只是type将所有旧类的类型声明为“实例”。提到这个问题
尹达仁

@DarrenYin并非总是如此,type(o)并且o.__class__ 总是返回相同的东西。链接问题中最受支持的答案说,但链接时不存在。此外,type所需的键入次数更少,并且看起来像公共API函数(没有下划线)。
WloHu

172
isinstance(obj, tuple)
isinstance(obj, basestring)
isinstance(obj, int)

谢谢回复; 这对于在运行程序时进行检查非常有用,但是我尝试在使用pdb调试时获取值。这是避免问题的好方法!

27

利用实例?

if isinstance(var, int):

if isinstance(var, str):

if isinstance(var, tuple):

测试str将在unicode字符串上失败。而且,isinstance(var, tuple)将错过任何碰巧是lists的变量,这些变量通常在诸如此类的情况下出现。当然,如果var是的实例,则可能要出错list,但是最好确保您知道在不同情况下会发生什么。
尹达仁

4
在Python 3中,您可以使用一系列类型进行测试:isinstance(var, (tuple, list))
bugmenot123 '18

有趣的是,尽管您先回答,但另一个人得到了所有的支持。
qwerty_so

10

请注意,如果您想在if语句中检查var类型,则该构造 if type(varname) == "tuple":将无法工作。但是这些将:

if type(varname) is tuple:
if type(varname) is list:
if type(varname) is dict:
if type(varname) is int:
if type(varname) is str:

4
您应该真正使用isinstance代替。当涉及到继承时,type()是危险的。
bugmenot123 '18

@ bugmenot123,我没有介绍所有可能的结果,我是在记录人们在尝试检查类型时通常会犯的错误,然后在不起作用时感到惊讶。否则,您绝对正确。
Goujon

希望您不介意,但我自己引用了您的答案,并提出了另一种方法。如果您愿意,我会删除参考。谢谢。
WinEunuuchs2Unix

@ WinEunuuchs2Unix,尽管在我看来,用'=='代替'is'也不是不同的方法,但我一点也不介意。
Goujon

4

您可能想使用进行测试(假设使用Python 2.x)isinstance(obj, basestring)。您可以选择使用isinstancetype和调用属性__class__,但isinstance很可能是您想要的。请看一下这篇文章,以更彻底地处理这三种选择之间的差异。


谢谢达伦;我可能会根据您的建议进行测试,但此刻我正在使用pdb。因此,我可以找出哪个是有问题的var,并避免犯同样的错误(我喜欢防御性编码,但同时我更喜欢避免首先犯错,而不是依靠检查来发现可能的错误错误)。有趣的是,还有class属性;从来没有听说过。

1

repr(object)将给出对象的文字说明,其中应显示类型和值。您可以在调试器中打印或查看它。

对于简单值,repr通常返回与在代码中按字面值写入值相同的字符串。对于自定义类,它提供了类名和对象ID,如果类是

__repr__

被覆盖。


感谢您回复Jurgen。我尝试过repr,但是它返回了变量*的值(在我的情况下为字符串),所以它的作用与p(varname)相同...我做错了,因为我应该看到您所说的,键入,对象的值和说明?

1
否。它返回str或unicode的字符串文字(包括引号),因此您应将其识别为该类型。对于整数类型,它返回未加引号的数字;对于其他数字类型,它返回相似的数字。对于自定义类A,默认情况下它返回类似<mymodule.0x123456处的实例>之类的内容,但是某些类会覆盖此描述字符串。
尔根·斯特罗贝尔

-2

为了补充Goujon的答案,请考虑以下混合整数和元组的列表:

for f in fills:
    print (type(f), f)
    if type(f)==int : print "INTEGER!!!"

生成此输出:

(<type 'int'>, 0)
INTEGER!!!
(<type 'tuple'>, (62973, 39058, 25708, 102))
(<type 'int'>, 1)
INTEGER!!!
(<type 'tuple'>, (16968, 12069, 3329, 102))
(<type 'int'>, 2)
INTEGER!!!
(<type 'tuple'>, (24939, 62205, 30062, 102))
(<type 'tuple'>, (32911, 32911, 0, 153))
(<type 'tuple'>, (32911, 0, 0, 153))
(<type 'tuple'>, (32911, 0, 32911, 153))
(<type 'tuple'>, (65535, 0, 0, 153))
(<type 'tuple'>, (0, 0, 65535, 153))
(<type 'tuple'>, (0, 32911, 0, 153))
(<type 'tuple'>, (0, 65535, 65535, 153))

因此,秘诀不是测试"int"字符串,而是测试int关键字。如果您像我一样,并且从Bash脚本世界迁移,那么==在Python脚本世界中使用测试可能是您的第一步。


1
您尚未正确阅读Goujon的答案。他们专门写道:“如果type(varname)==“ tuple”:的构造将不起作用”,然后解释了正确的方法。
kaya3

@ kaya3在我的回答中,我试图说是否删除了"双引号。
WinEunuuchs2Unix

2
我理解您在回答中写的内容;这是错误的,因为您是说Goujon的答案犯了这个错误,而事实上Goujon的答案却确定这是一个错误。您的解决方法与Goujon写的解决该问题的方法相同。
kaya3

@ kaya3我已经改写了答案,并解释了为什么==对像我这样的人很重要。现在可以吗?
WinEunuuchs2Unix

1
您的答案不再是错误的,但是除了可以使用==而不是is您愿意时,不清楚您添加到现有答案中的内容。除了在非常罕见的边缘情况下没有实际区别,在这些情况下is是正确的选择。
kaya3
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.