Как определить тип переменной Python?


1569

Как узнать тип переменной: 32-разрядная без знака, 16-разрядная со знаком и т. Д.?

Как мне это увидеть?



Ответы:


1381

Используйте type()встроенную функцию:

>>> i = 123
>>> type(i)
<type 'int'>
>>> type(i) is int
True
>>> i = 123.456
>>> type(i)
<type 'float'>
>>> type(i) is float
True

Чтобы проверить, принадлежит ли переменная данного типа, используйте isinstance:

>>> i = 123
>>> isinstance(i, int)
True
>>> isinstance(i, (float, str, set, dict))
False

Обратите внимание, что Python не имеет те же типы, что и C / C ++, что кажется вашим вопросом.


437

Возможно, вы ищете встроенную функцию .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'>

Мне пришлось дважды взять, когда я увидел это. Java SE8 теперь содержит целые числа без знака, и я настолько развил их, что кажется греховным, что у Java никогда не было целых чисел без знака до SE8.
dddJewelsbbb


110

Как определить тип переменной в Python?

Так что если у вас есть переменная, например:

one = 1

Вы хотите знать его тип?

В Python есть правильные и неправильные способы делать практически все. Вот правильный путь:

использование type

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

Вы можете использовать __name__атрибут, чтобы получить имя объекта. (Это один из немногих специальных атрибутов, для которого нужно использовать __dunder__имя, чтобы добраться до него - в inspectмодуле даже нет метода для него .)

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

Не использовать __class__

В Python имена, начинающиеся с подчеркиваний, семантически не являются частью общедоступного API, и пользователям рекомендуется избегать их использования. (За исключением случаев, когда это абсолютно необходимо.)

Так как typeдает нам класс объекта, мы должны избегать его получения напрямую. :

>>> one.__class__

Обычно это первая идея, которую люди имеют при доступе к типу объекта в методе - они уже ищут атрибуты, поэтому тип кажется странным. Например:

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

Не. Вместо этого, введите (self):

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

Детали реализации целых и чисел

Как узнать тип переменной: 32-разрядная без знака, 16-разрядная со знаком и т. Д.?

В Python эти особенности являются деталями реализации. Итак, в общем, мы обычно не беспокоимся об этом в Python. Однако, чтобы удовлетворить ваше любопытство ...

В Python 2 int обычно представляет собой целое число со знаком, равное ширине слова реализации (ограничено системой). Это обычно реализуется как долго C . Когда целые числа становятся больше этого значения, мы обычно конвертируем их в длинные Python (с неограниченной точностью, не путать с длинными C).

Например, в 32-битном Python 2 мы можем вывести, что int является 32-битным целым числом со знаком:

>>> import sys

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

В Python 3 старый int исчезает, и мы просто используем (Python) long как int, который имеет неограниченную точность.

Мы также можем получить некоторую информацию о числах с плавающей точкой в ​​Python, которые обычно реализуются как двойные в C:

>>> 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 для получения типа переменной. Используйте typeвместо этого.

И не беспокойтесь о деталях реализации Python. Я сам не сталкивался с проблемами вокруг этого. Вы, вероятно, тоже не будете, и если вы действительно это сделаете, вы должны знать достаточно, чтобы не искать этот ответ для того, что делать.


типа выходит как <type instance>но __class__дает email.message.Message- что я делаю не так?
Ясен

@Jasen Вы используете Python 2 и не наследуете от object?
Аарон Холл

да, просто не используя import email классы моего собственного изобретения.
Jasen

65
print type(variable_name)

Я также настоятельно рекомендую интерактивный переводчик IPython при решении таких вопросов. Он позволяет вам печатать variable_name?и возвращает полный список информации об объекте, включая тип и строку документа для типа.

например

In [9]: var = 123

In [10]: var?
Type:       int
Base Class: <type 'int'>
String Form:    123
Namespace:  Interactive
Docstring:
    int(x[, base]) -> integer

Преобразуйте строку или число в целое число, если это возможно. Аргумент с плавающей запятой будет обрезан до нуля (это не включает строковое представление числа с плавающей запятой!) При преобразовании строки используйте необязательную базу. Неправильно указывать базу при преобразовании не-строки. Если аргумент находится за пределами целочисленного диапазона, вместо него будет возвращен длинный объект.


2
Я попросил неподписанный int, подписанный int и т. Д.
user46646

3
print type(str)возвращает ошибку в Python 3.6. Использованиеtype(str)
Колоб Каньон

4
@KolobCanyon, потому что в 3.x для печати нужно использовать круглые скобки:print(type(str))
jcoppens

1
Вы должны действительно изменить print type(var)ошибочный код.
Хань Сяо

54
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.

40

Еще один способ использования __class__:

>>> a = [1, 2, 3, 4]
>>> a.__class__
<type 'list'>
>>> b = {'key1': 'val1'}
>>> b.__class__
<type 'dict'>
>>> c = 12
>>> c.__class__
<type 'int'>

1
re: прокомментируйте «имена, начинающиеся с подчеркивания ...» (одиночные), подчеркивания сильно отличаются от двойных подчеркиваний («лишние»), и они, безусловно, являются частью общедоступного API, и их, безусловно, можно использовать. Это может помочь ... youtu.be/wf-BqAjZb8M
Майкл

31

Примеры простой проверки типов в Python:

assert type(variable_name) == int

assert type(variable_name) == bool

assert type(variable_name) == list

29

Это может быть немного неактуально. но вы можете проверить типы объектов, isinstance(object, type)как указано здесь .


1
Я думаю, что это намного лучше, чем функция типа для использования в процессе проверки. Если вы хотите проверить результат и действовать с ним, вы должны использовать try catch с типом, но isinstance возвращает значение true или false
alkanschtein

24

Вопрос несколько двусмысленный - я не уверен, что вы подразумеваете под «взглядом». Если вы пытаетесь запросить тип нативного объекта Python, ответ @atzz направит вас в правильном направлении.

Однако, если вы пытаетесь сгенерировать объекты Python, которые имеют семантику примитивных C-типов (например uint32_t, int16_t), используйте structмодуль. Таким образом вы можете определить количество битов в данном примитиве C-типа:

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

Это также отражено в arrayмодуле, который может создавать массивы следующих типов нижнего уровня:

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

7
Вопрос, насколько я понимаю, задает вопрос о типе «переменной» в Python. Ваш ответ в целом правильный, но не по теме.
tzot

19

Вы имеете в виду Python или использование ctypes ?

В первом случае вы просто не можете - потому что Python не имеет 16/32-битных целых чисел со знаком / без знака.

Во втором случае вы можете использовать type():

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

Для получения дополнительной информации о ctypes и его типе см. Официальную документацию .


15

Python не имеет таких типов, как вы описываете. Существует два типа, используемых для представления целых значений:, intкоторый соответствует типу int платформы в C, и long, который является целым числом произвольной точности (то есть он растет по мере необходимости и не имеет верхнего предела). ints автоматически преобразуются в, longесли выражение дает результат, который не может быть сохранен в int.


11

Простой, для питона 3.4 и выше

print (type(variable_name))

Python 2.7 и выше

print type(variable_name)

10

Это действительно зависит от того, какой уровень вы имеете в виду. В Python 2.x есть два целочисленных типа int(с ограничением sys.maxint) и long(с неограниченной точностью) по историческим причинам. В коде Python это не должно иметь большого значения, потому что интерпретатор автоматически конвертирует в long, когда число слишком велико. Если вы хотите узнать о фактических типах данных, используемых в базовом интерпретаторе, это зависит от реализации. (CPython находятся в Objects / intobject.c и Objects / longobject.c.) Чтобы узнать о типах систем, посмотрите ответ cdleary для использования модуля struct.



-29

Только не делай этого. Просить что-то типа неправильно само по себе. Вместо этого используйте полиморфизм. Найдите или, при необходимости, определите самостоятельно метод, который делает то, что вы хотите для любого возможного типа ввода, и просто вызывайте его, ничего не спрашивая. Если вам нужно работать со встроенными типами или типами, определенными сторонней библиотекой, вы всегда можете наследовать их и использовать вместо этого собственные производные. Или вы можете обернуть их в своем классе. Это объектно-ориентированный способ решения таких проблем.

Если вы настаиваете на проверке точного типа и размещении грязных ifs здесь и там, вы можете использовать __class__свойство или typeфункцию, чтобы сделать это, но вскоре вы обнаружите, что обновляете все эти ifs дополнительными случаями каждые два или три коммита. Делая это, OO предотвращает это и позволяет вам определять новый класс только для нового типа ввода.


4
Я действительно не знаю, что этот ответ добавил к существующим (возможно, кроме первого предложения?)
user2305193
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.