Як перевірити, чи є змінна класом чи ні?


236

Мені було цікаво, як перевірити, чи є змінна класом (а не екземпляром!) Чи ні.

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

Наприклад, у наступному коді

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

Я спробував замінити " class" на ??? , але я зрозумів, що classце ключове слово в python.

Відповіді:


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.
доттаул

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

5
пам’ятайтеimport types
nguyên

13
types.ClassTypeбільше не потрібен в Python 3 (і видаляється).
kawing-chiu

це не працює з новими класами стилів взагалі .... навіть у python 2. не використовуйте це рішення поодинці
Ерік Аронесті

Це було взято з модуля перевірки, тому я сумніваюся, що він не працює. Наприклад, просто перевірити з Python2.7In [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 .
Martijn Pieters

39
>>> class X(object):
...     pass
... 
>>> type(X)
<type 'type'>
>>> isinstance(X,type)
True

1
Гм ... Приємна відповідь, але коли я ввожу (Foo) у своєму класі Foo, він говорить <type 'classobj'> замість <type 'type'>. Я припускаю, що різниця походить від того, що X успадковує від об'єкта, але Foo це не так. Чи є якась інша від цього різниця? Дякую.
jeeyoungk

6
Це не працює для класів старого стилю:, 'class Old:pass' 'isinstance(Old, type) == False'але inspect.isclass(Old) == True.
jfs

1
@jeeyoungk: Ви не "припускаєте, що різниця походить від ...", ви насправді читаєте це в коді. Підклас об'єкта ("новий стиль") має бажані властивості, саме те, що ви бачите тут.
С.Лотт

12
Ось підказка - оскільки це працює для класів нового стилю, не використовуйте класи старого стилю. Немає сенсу використовувати класи старого стилю.
С.Лотт

isin substance (e, f) E - це об'єкт, що створюється, F - об'єкт класу.
Декстер

24
isinstance(X, type)

Поверніть, Trueякщо Xце клас, а Falseякщо ні.


3
Я стає хибним, навіть якщо X - клас.
Mads Skjern

6
Це працює лише для нових класів стилів. Класи старого стилю мають тип 'classobj'. Тож якщо ви використовуєте класи старого стилю, ви можете: імпортувати типи isin substance (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, ось код з type.py :

class _C:
    def _m(self): pass
ClassType = type(_C)

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

types.ClassTypeбуло видалено в Python 3
Beau Barker
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.