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


当前回答

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

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

其他回答

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。

a = "cool"
type(a)

//result 'str'
<class 'str'>
or 
do 
`dir(a)` 
to see the list of inbuilt methods you can have on the variable.

你的意思是用Python还是用ctypes?

在第一种情况下,您根本不可能——因为Python没有带符号/无符号的16/32位整数。

在第二种情况下,可以使用type():

>>> import ctypes
>>> a = ctypes.c_uint() # unsigned int
>>> type(a)
<class 'ctypes.c_ulong'>

有关ctypes及其类型的更多参考信息,请参阅官方文档。

这个问题有些模棱两可——我不确定你所说的“观点”是什么意思。如果您试图查询本地Python对象的类型,@atzz的答案将引导您朝着正确的方向前进。

但是,如果您试图生成具有原始C类型语义的Python对象(例如uint32_t、int16_t),请使用结构模块。因此,您可以确定给定C型原语中的位数:

>>> struct.calcsize('c') # char
1
>>> struct.calcsize('h') # short
2
>>> struct.calcsize('i') # int
4
>>> struct.calcsize('l') # long
4

这也反映在数组模块中,它可以生成以下较低级别类型的数组:

>>> array.array('c').itemsize # char
1

支持的最大整数(Python 2的int)由sys.maxint给出。

>>> import sys, math
>>> math.ceil(math.log(sys.maxint, 2)) + 1 # Signedness
32.0

还有sys.getsizeof,它返回剩余内存中Python对象的实际大小:

>>> a = 5
>>> sys.getsizeof(a) # Residual memory.
12

对于浮点数据和精度数据,请使用sys.float_info:

>>> 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)

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

my_variable = 5

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

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