Як визначити тип змінної Python?


1566

Як я бачу тип змінної, чи є вона непідписаною 32-бітовою, підписаною 16-бітовою тощо?

Як я його переглядаю?



Відповіді:


1379

Використовуйте 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)

Деталі реалізації ints та floats

Як я бачу тип змінної, чи є вона непідписаною 32-бітовою, підписаною 16-бітовою тощо?

У Python ці специфіки є деталями реалізації. Тож загалом у Python ми зазвичай не хвилюємося цим. Однак, щоб задовольнити свою цікавість ...

У Python 2, int, як правило, підписане ціле число, рівне ширині слова реалізації (обмежена системою). Це зазвичай реалізується як довго C . Коли цілі числа стають більшими за це, ми зазвичай перетворюємо їх на довгі Python (з необмеженою точністю, щоб не плутати їх із C longs).

Наприклад, з 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's) довгий як 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 не використовуючи класів власного винаходу.
Ясен

65
print type(variable_name)

Я також настійно рекомендую інтерактивний інтерпретатор IPython при вирішенні таких питань. Це дозволяє вводити variable_name?і повертає цілий список інформації про об'єкт, включаючи тип і рядок doc для типу.

напр

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 etc.
user46646

3
print type(str)повертає помилку в Python 3.6. Використанняtype(str)
Калоб Колоб

4
@KolobCanyon це тому, що в 3.x для друку потрібні дужки:print(type(str))
jcoppens

1
Вам слід дійсно змінити print type(var)помилковий код.
Хань XIAO

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
michael

31

Приклади простої перевірки типу в Python:

assert type(variable_name) == int

assert type(variable_name) == bool

assert type(variable_name) == list

29

Це може бути мало не має значення. але ви можете перевірити типи об’єктів, isinstance(object, type)як зазначено тут .


1
Я думаю, що це набагато краще, ніж функція типу, яка використовується для перевірки. Якщо ви хочете перевірити і діяти з результатом, вам доведеться скористатися спробувати catch з типом, але речовина повертає справжнє або хибне
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'>

Докладніше про типи, його тип, дивіться в офіційній документації .


15

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


11

Простий, для python 3.4 та вище

print (type(variable_name))

Python 2.7 і вище

print type(variable_name)

10

Це дійсно залежить від того, на якому рівні ви маєте на увазі. У Python 2.x є два цілих типи int(з обмеженням sys.maxint) та long(необмежена точність) з історичних причин. У коді Python це не має нічого різного, оскільки інтерпретатор автоматично перетворюється на довгий, коли число занадто велике. Якщо ви хочете дізнатися про фактичні типи даних, що використовуються в базовому інтерпретаторі, це залежить від реалізації. (CPython розташовані в Objects / intobject.c та Object / longobject.c.) Щоб дізнатися про типи систем, подивіться відповідь cdleary для використання структури модуля.



-29

Тільки не робіть цього. Просити щось типу невірно саме по собі. Замість цього використовуйте поліморфізм. Знайдіть або, якщо потрібно, визначте сам метод, який виконує те, що ви хочете, для будь-якого можливого типу введення, та просто зателефонуйте йому, нічого не питаючи. Якщо вам потрібно працювати з вбудованими типами або типами, визначеними сторонніми бібліотеками, ви завжди можете успадкувати їх і використовувати замість цього свої власні похідні. Або ви можете загорнути їх у свій власний клас. Це об’єктно-орієнтований спосіб вирішення таких проблем.

Якщо ви наполягаєте на тому, щоб перевірити точний тип і розмістити деякі брудні ifs тут і там, ви можете використовувати __class__властивість або typeфункцію для цього, але незабаром ви оновлюєте всі ці дані ifдодатковими справами кожні два-три коміти. Виконання цього способу OO перешкоджає цьому і дозволяє вам натомість визначати новий клас для нового типу введення.


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