如何查看变量的类型?(例如无符号32位)


当前回答

我在刚接触Python时(现在仍然如此)看到了这个:

x = …
print(type(x))```

其他回答

Python是一种动态类型语言。最初创建为字符串的变量可以稍后重新分配为整数或浮点。翻译不会抱怨:

name = "AnyValue"
# Dynamically typed language lets you do this:
name = 21
name = None
name = Exception()

要检查变量的类型,可以使用type()或isinstance()内置函数。让我们看看他们的行动:

Python3示例:

variable = "hello_world"
print(type(variable) is str) # True
print(isinstance(variable, str)) # True

让我们比较两种方法在python3中的性能

python3 -m timeit -s "variable = 'hello_world'" "type(variable) is int"
5000000 loops, best of 5: 54.5 nsec per loop

python3 -m timeit -s "variable = 'hello_world'" "isinstance(variable, str)"
10000000 loops, best of 5: 39.2 nsec per loop

类型大约慢40%(54.5/39.2=1.390)。

我们可以改用type(variable)==str。这会奏效,但这是个坏主意:

要检查变量的值时,应使用==。我们将使用它来查看变量的值是否等于“hello_world”。但是当我们要检查变量是否为字符串时,运算符是否更合适。有关何时使用其中一个或另一个的更详细说明,请查看本文。==更慢:python3-m timeit-s“variable='hello_world'”“type(variable)==str”5000000个循环,每个循环最好为5:64.4 nsec

身份和类型的区别

速度并不是这两种功能之间的唯一区别。实际上,它们的工作方式有一个重要区别:

type只返回对象的类型(它是类)。我们可以使用它来检查变量的类型是否为str。isinstance检查给定对象(第一个参数)是否为:指定为第二个参数的类的实例。例如,变量是str类的实例吗?或指定为第二参数的类的子类的实例。换句话说,变量是str子类的实例吗?

这在实践中意味着什么?假设我们希望有一个自定义类充当列表,但有一些其他方法。因此,我们可以对列表类型进行子类化,并在其中添加自定义函数:

class MyAwesomeList(list):
    # Add additional functions here
    pass

但是现在,如果我们将这个新类与列表进行比较,则类型和isinstance返回不同的结果!

my_list = MyAwesomeList()
print(type(my_list) is list) # False
print(isinstance(my_list, list)) # True

我们得到不同的结果,因为isinstance检查my_list是列表的一个实例(不是)还是列表的一个子类(因为MyAwesomeList是列表的子类)。如果您忘记了这一差异,它可能会导致代码中出现一些细微的错误。

结论

isinstance通常是比较类型的首选方式。它不仅速度更快,而且考虑了继承,这通常是所需的行为。在Python中,您通常希望检查给定对象的行为是否像字符串或列表,而不一定是字符串。所以,不用检查字符串及其所有自定义子类,只需使用isinstance即可。

另一方面,当您想要显式检查给定变量是否为特定类型(而不是其子类)时,请使用类型。当您使用它时,请这样使用:type(var)is some_type not like this:type(var)==some_type。

您应该使用type()函数。像这样:

my_variable = 5

print(type(my_variable)) # Would print out <class 'int'>

此函数将查看任何变量的类型,无论是列表还是类。查看此网站了解更多信息:https://www.w3schools.com/python/ref_func_type.asp

您可能正在查找type()内置函数。

请参见下面的示例,但Python中没有像Java一样的“无符号”类型。

正整数:

>>> v = 10
>>> type(v)
<type 'int'>

大正整数:

>>> v = 100000000000000
>>> type(v)
<type 'long'>

负整数:

>>> v = -10
>>> type(v)
<type 'int'>

文字顺序:

>>> v = 'hi'
>>> type(v)
<type 'str'>

浮点整数:

>>> v = 3.14159
>>> type(v)
<type 'float'>

如何确定Python中的变量类型?

因此,如果您有一个变量,例如:

one = 1

你想知道它的类型吗?

在Python中,有正确的方法和错误的方法可以做任何事情。这是正确的方法:

使用类型

>>> type(one)
<type 'int'>

您可以使用__name__属性获取对象的名称。(这是少数需要使用__dunder__名称才能访问的特殊属性之一——inspect模块中甚至没有一个方法。)

>>> type(one).__name__
'int'

不要使用__class__

在Python中,以下划线开头的名称在语义上不是公共API的一部分,用户最好避免使用它们。(除非绝对必要。)

由于类型为我们提供了对象的类,因此我们应该避免直接获取该类

>>> one.__class__

这通常是人们在访问方法中对象类型时的第一个想法——他们已经在寻找属性,所以类型看起来很奇怪。例如:

class Foo(object):
    def foo(self):
        self.__class__

不要。而是键入(self):

class Foo(object):
    def foo(self):
        type(self)

int和float的实现细节

如何查看变量的类型,无论它是无符号32位、有符号16位等。?

在Python中,这些细节是实现细节。所以,一般来说,我们在Python中通常不会担心这一点。然而,为了满足你的好奇心。。。

在Python 2中,int通常是一个有符号整数,等于实现的字宽(受系统限制)。它通常在C中实现为long。当整数大于此值时,我们通常将它们转换为Python long(精度无限,不要与C long混淆)。

例如,在32位Python 2中,我们可以推断int是一个有符号的32位整数:

>>> import sys

>>> format(sys.maxint, '032b')
'01111111111111111111111111111111'
>>> format(-sys.maxint - 1, '032b') # minimum value, see docs.
'-10000000000000000000000000000000'

在Python3中,旧的int已经消失,我们只使用(Python的)long作为int,它具有无限的精度。

我们还可以获得一些关于Python的浮点数的信息,这些浮点数通常在C中实现为double:

>>> sys.float_info
sys.floatinfo(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, 
min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, 
mant_dig=53, epsilon=2.2204460492503131e-16, radix=2, rounds=1)

结论

不要使用__class__(一个语义上非公共的API)来获取变量的类型。请改用类型。

不要太担心Python的实现细节。我不必亲自处理这方面的问题。你可能也不会,如果你真的这样做了,你应该知道,不要去寻找这个答案。

不要这样做。要求某种类型的东西本身就是错误的。而是使用多态性。查找或在必要时自行定义一个方法,该方法可以为任何可能类型的输入执行所需的操作,只需调用它,而无需询问任何问题。如果您需要使用内置类型或由第三方库定义的类型,您可以始终从它们继承并使用自己的派生类型。或者你可以把它们包装在自己的班级里。这是解决此类问题的面向对象方法。

如果你坚持要检查确切的类型,并在这里和那里放置一些肮脏的If,你可以使用__class__属性或类型函数来完成,但很快你就会发现自己每两次或三次提交就会更新所有这些If并添加额外的case。使用OO方法可以防止这种情况,并且只允许为新类型的输入定义一个新类。