Как проверить, является ли переменная классом или нет?

236

Мне было интересно, как проверить, является ли переменная классом (не экземпляром!) Или нет.

Я пытался использовать функцию, isinstance(object, class_or_type_or_tuple)чтобы сделать это, но я не знаю, какой тип будет иметь класс.

Например, в следующем коде

class Foo: pass  
isinstance(Foo, **???**) # i want to make this return True.

Я пытался заменить " class" с ??? , но я понял, что classэто ключевое слово в Python.

jeeyoungk
источник

Ответы:

335

Еще лучше: используйте inspect.isclassфункцию.

>>> import inspect
>>> class X(object):
...     pass
... 
>>> inspect.isclass(X)
True

>>> x = X()
>>> isinstance(x, X)
True
>>> y = 25
>>> isinstance(y, X)
False
Бенджамин Петерсон
источник
7
Если вы также хотите inspect.isclassвернуть, Trueесли объект для проверки является экземпляром класса , используйтеinspect.isclass(type(Myclass()))
michaelmeyer
8
Лучше чем что :)?
Безумный физик
8
@michaelmeyer type(whatever)всегда возвращает объект, который является классом, поэтому эта проверка избыточна. Если этого не произойдет, не будет никакого способа создать экземпляр, whateverи, таким образом, вы не сможете выполнить проверку в первую очередь.
a_guest
Не работает для меня Использование python3 с snakemake, type(snakemake.utils)возвращает <class 'module'>и все же inspect.isclass(snakemake.utils)возвращает False.
tedtoal
3
Это потому snakemake.utilчто модуль не класс?
Бенджамин Петерсон
44

Inspect.isclass, вероятно, лучшее решение, и действительно легко увидеть, как оно на самом деле реализовано.

def isclass(object):
    """Return true if the object is a class.

    Class objects provide these attributes:
        __doc__         documentation string
        __module__      name of module in which this class was defined"""
    return isinstance(object, (type, types.ClassType))
andrea_crotti
источник
5
помнитеimport types
nguyên
13
types.ClassTypeбольше не требуется в Python 3 (и удаляется).
kawing-chiu
это не работает с новыми классами стилей вообще .... даже в python 2. не используйте это решение в одиночку
Erik Aronesty
Это было взято из модуля проверки, поэтому я сомневаюсь, что это не работает. Например, с Python2.7 это просто проверитьIn [8]: class NewStyle(object): ...: pass ...: In [9]: isinstance(NewStyle, (type, types.ClassType)) Out[9]: True
andrea_crotti
Это реализация Python 2, которая должна обрабатывать классы старого и нового стиля. Python 3 упрощает это до isinstance(object, type). Обратите внимание , что объекты , такие как int, list, strи т.д., также классы, так что вы не можете использовать это , чтобы различать пользовательские классы , определенные в Python и встроенных классов , определенных в коде C .
Мартин Питерс
39
>>> class X(object):
...     pass
... 
>>> type(X)
<type 'type'>
>>> isinstance(X,type)
True
С. Лотт
источник
1
Хм ... Хороший ответ, но когда я делаю type (Foo) в своем классе Foo, он говорит <type 'classobj'> вместо <type 'type'>. Я предполагаю, что различие происходит от того факта, что X наследует от объекта, а Foo - нет. Есть ли какая-то другая разница, вытекающая из этого? Спасибо.
jeeyoungk
6
Это не работает для классов старого стиля:, 'class Old:pass' 'isinstance(Old, type) == False'но inspect.isclass(Old) == True.
JFS
1
@jeeyoungk: Вы не «предполагаете, что разница происходит от ...», вы фактически читаете это в коде. Подкласс объекта («новый стиль») имеет желаемые свойства, именно то, что вы видите здесь.
S.Lott
12
Вот подсказка - поскольку это работает для классов нового стиля, не используйте классы старого стиля. Нет смысла использовать классы старого стиля.
С.Лотт
isinstance (e, f) E - экземпляр объекта, F - объект класса.
Декстер
24
isinstance(X, type)

Вернуть, Trueесли Xэто класс, а Falseесли нет.

qnub
источник
3
Я получаю Ложь, даже если Х класс.
Мадс Скьерн
6
Это работает только для новых классов стилей. Классы старого стиля имеют тип 'classobj'. Поэтому, если вы используете классы старого стиля, вы можете это сделать: импортировать типы isinstance (X, types.ClassType)
Charles L.
2
Это похоже на то S. Lott's answer, что на четыре года старше.
Итан Фурман
5

Эта проверка совместима как с Python 2.x, так и с Python 3.x.

import six
isinstance(obj, six.class_types)

По сути, это функция-обертка, которая выполняет ту же проверку, что и в ответе andrea_crotti.

Пример:

>>> import datetime
>>> isinstance(datetime.date, six.class_types)
>>> True
>>> isinstance(datetime.date.min, six.class_types)
>>> False
Сергей
источник
1

класс Foo: называется классом старого стиля, а класс X (объект): называется классом нового стиля.

Проверьте это В чем разница между старым стилем и новым стилем классов в Python? , Новый стиль рекомендуется. Читайте о " объединении типов и классов "

СП.
источник
6
Это должен был быть комментарий, возможно?
Кос
1

Простейшим способом является использование в том inspect.isclassвиде, в каком оно опубликовано в наиболее проголосовавшем ответе.
Подробности реализации можно найти на python2 inspect и python3 inspect .
для класса нового стиля: isinstance(object, type)
для класса старого стиля: isinstance(object, types.ClassType)
em, для класса старого стиля, который он использует types.ClassType, вот код из types.py :

class _C:
    def _m(self): pass
ClassType = type(_C)
lyu.l
источник
1

Бенджамин Петерсон прав насчет использования inspect.isclass()для этой работы. Но обратите внимание, что вы можете проверить, является ли ClassобъектClass и, следовательно, неявным образом a Class, используя встроенную функцию issubclass . В зависимости от вашего варианта использования это может быть более питонным.

from typing import Type, Any
def isclass(cl: Type[Any]):
    try:
        return issubclass(cl, cl)
    except TypeError:
        return False

Затем можно использовать так:

>>> class X():
...     pass
... 
>>> isclass(X)
True
>>> isclass(X())
False
мази
источник
-2

Здесь уже есть некоторые рабочие решения, но вот еще одно:

>>> import types
>>> class Dummy: pass
>>> type(Dummy) is types.ClassType
True
Ztyx
источник
types.ClassTypeбыл удален в Python 3
Бо Баркер