Jak sprawdzić, czy zmienna jest klasą, czy nie?


236

Zastanawiałem się, jak sprawdzić, czy zmienna jest klasą (a nie instancją!), Czy nie.

Próbowałem użyć tej funkcji isinstance(object, class_or_type_or_tuple), ale nie wiem, jaki typ będzie miał klasa.

Na przykład w następującym kodzie

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

Próbowałem zastąpić „ class??? , ale zdałem sobie sprawę, że classjest to słowo kluczowe w pythonie.

Odpowiedzi:


335

Jeszcze lepiej: użyj inspect.isclassfunkcji.

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

>>> x = X()
>>> isinstance(x, X)
True
>>> y = 25
>>> isinstance(y, X)
False

7
Jeśli chcesz również inspect.isclasszwrócić, Truejeśli obiekt do sprawdzenia jest instancją klasy , użyjinspect.isclass(type(Myclass()))
michaelmeyer 18.04.13

8
Lepsze niż co :)?
Szalony fizyk

8
@ michaelmeyer type(whatever)zawsze zwraca obiekt będący klasą, więc ta kontrola jest zbędna. Gdyby tak nie było, nie byłoby sposobu na utworzenie instancji, whatevera zatem nie można było przeprowadzić kontroli w pierwszej kolejności.
a_guest

Nie działa dla mnie. Używanie python3 z snakemake type(snakemake.utils)zwraca <class 'module'>i jeszcze inspect.isclass(snakemake.utils)zwraca False.
tedtoal,

3
To dlatego, że snakemake.utilmoduł nie jest klasą?
Benjamin Peterson

44

Inspect.isclass jest prawdopodobnie najlepszym rozwiązaniem i naprawdę łatwo jest zobaczyć, jak jest faktycznie wdrożony

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
pamiętajcieimport types
nguyên

13
types.ClassTypenie jest już potrzebny w Pythonie 3 (i został usunięty).
kawing-chiu

to w ogóle nie działa z klasami nowego stylu .... nawet w Pythonie 2. nie używaj tego rozwiązania samodzielnie
Erik Aronesty

To zostało pobrane z modułu inspekcji, więc wątpię, żeby to nie działało. Łatwo to sprawdzić na przykład w Python2.7In [8]: class NewStyle(object): ...: pass ...: In [9]: isinstance(NewStyle, (type, types.ClassType)) Out[9]: True
andrea_crotti 27.04.17

Jest to implementacja języka Python 2, która musi obsługiwać klasy w starym i nowym stylu. Python 3 upraszcza to isinstance(object, type). Należy pamiętać, że obiekty podoba int, list, str, itd. Są również zajęcia, więc nie można użyć tego odróżnić niestandardowych klas zdefiniowanych w Pythonie i wbudowanych klas zdefiniowanych w kodzie C .
Martijn Pieters

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

1
Hm ... Niezła odpowiedź, ale kiedy piszę (Foo) na mojej klasie Foo, pojawia się napis <type 'classobj'> zamiast <type 'type'>. Zakładam, że różnica wynika z faktu, że X dziedziczy po obiekcie, ale Foo nie. Czy wynika z tego jakaś inna różnica? Dzięki.
jeeyoungk

6
Nie działa dla klas w starym stylu:, 'class Old:pass' 'isinstance(Old, type) == False'ale inspect.isclass(Old) == True.
jfs

1
@jeeyoungk: Nie „zakładasz, że różnica wynika z ...”, w rzeczywistości czytasz to w kodzie. Podklasa obiektu („nowy styl”) ma pożądane właściwości, dokładnie tak, jak tutaj.
S.Lott,

12
Oto wskazówka - ponieważ działa to dla klas w nowym stylu, nie używaj klas w starym stylu. Nie ma sensu używać klas w starym stylu.
S.Lott,

isinstance (e, f) E to obiekt instancji, F to obiekt klasy.
Dexter

24
isinstance(X, type)

Zwróć, Truejeśli Xjest klasą, a Falsejeśli nie.


3
Dostaję False, nawet jeśli X jest klasą.
Mads Skjern

6
Działa to tylko w przypadku klas nowego stylu. Klasy starego stylu są typu „classobj”. Więc jeśli używasz klas starego stylu, możesz to zrobić: importuj typy isinstance (X, types.ClassType)
Charles L.

2
Wygląda na to, że S. Lott's answerjest o cztery lata starszy.
Ethan Furman,

5

Ta kontrola jest zgodna zarówno z Python 2.x, jak i Python 3.x.

import six
isinstance(obj, six.class_types)

Jest to w zasadzie funkcja otoki, która wykonuje to samo sprawdzenie, co w odpowiedzi andrea_crotti.

Przykład:

>>> import datetime
>>> isinstance(datetime.date, six.class_types)
>>> True
>>> isinstance(datetime.date.min, six.class_types)
>>> False


1

najprostszym sposobem jest użycie tego, inspect.isclassjak podano w najczęściej głosowanej odpowiedzi.
szczegóły implementacji można znaleźć na python2 inspect i python3 inspect .
dla klasy w nowym stylu: isinstance(object, type)
dla klasy w starym stylu: isinstance(object, types.ClassType)
em, dla klasy w starym stylu, używa types.ClassType, oto kod z types.py :

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

1

Benjamin Peterson ma rację co do wykorzystania inspect.isclass()tej pracy. Zauważ jednak, że możesz sprawdzić, czy Classobiekt jest konkretny Class, a zatem domyślnie a Class, używając wbudowanej funkcji issclcl . W zależności od przypadku użycia może to być bardziej pytoniczne.

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

Następnie można go użyć w następujący sposób:

>>> class X():
...     pass
... 
>>> isclass(X)
True
>>> isclass(X())
False

-2

Istnieją już pewne działające rozwiązania, ale oto inne:

>>> import types
>>> class Dummy: pass
>>> type(Dummy) is types.ClassType
True

types.ClassTypezostał usunięty w Pythonie 3
Beau Barker
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.