Bagaimana cara memeriksa apakah suatu variabel adalah kelas atau bukan?


236

Saya bertanya-tanya bagaimana cara memeriksa apakah variabel adalah kelas (bukan sebuah instance!) Atau tidak.

Saya sudah mencoba menggunakan fungsi isinstance(object, class_or_type_or_tuple)untuk melakukan ini, tetapi saya tidak tahu tipe apa yang akan dimiliki sebuah kelas.

Misalnya, dalam kode berikut

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

Saya mencoba mengganti " class" dengan ??? , tetapi saya menyadari bahwa itu classadalah kata kunci dalam python.

Jawaban:


335

Lebih baik lagi: gunakan inspect.isclassfungsinya.

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

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

7
Jika Anda juga ingin inspect.isclasskembali Truejika objek yang diperiksa adalah instance kelas , gunakaninspect.isclass(type(Myclass()))
— michaelmeyer

8
Lebih baik dari apa :)?
— Fisikawan Gila

8
@michaelmeyer type(whatever)selalu mengembalikan objek yang merupakan kelas, jadi pemeriksaan ini berlebihan. Jika tidak, tidak akan ada cara untuk instantiate whateverdan dengan demikian Anda tidak bisa melakukan pemeriksaan di tempat pertama.
— a_guest

Tidak bekerja untuk saya. Menggunakan python3 dengan snakemake, type(snakemake.utils)kembali <class 'module'>dan inspect.isclass(snakemake.utils)kembali False.
— tedtoal

3
Itu karena snakemake.utilmodul bukan kelas?
— Benjamin Peterson

44

Inspect.isclass mungkin merupakan solusi terbaik, dan sangat mudah untuk melihat bagaimana itu sebenarnya diimplementasikan

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
ingatimport types
— nguyên

13
types.ClassTypetidak lagi diperlukan dalam Python 3 (dan dihapus).
— kawing-chiu

ini tidak bekerja dengan kelas gaya baru sama sekali .... bahkan dalam python 2. jangan gunakan solusi ini sendirian
— Erik Aronesty

Itu diambil dari modul inspeksi jadi saya ragu itu tidak berhasil. Sangat mudah untuk memeriksa dengan Python2.7 misalnyaIn [8]: class NewStyle(object): ...: pass ...: In [9]: isinstance(NewStyle, (type, types.ClassType)) Out[9]: True
— andrea_crotti

Ini adalah implementasi Python 2, yang harus menangani kelas gaya lama dan gaya baru. Python 3 menyederhanakan ini menjadi isinstance(object, type). Perhatikan bahwa benda-benda seperti int, list, str, dll juga kelas, sehingga Anda tidak dapat menggunakan ini untuk membedakan antara kelas kustom didefinisikan dalam Python dan built-in kelas didefinisikan dalam kode C .
— Martijn Pieters

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

1
Hm ... Jawaban yang bagus, tetapi ketika saya mengetik (Foo) di kelas Foo saya, ia mengatakan <type 'classobj'> alih-alih <type 'type'>. Saya berasumsi bahwa perbedaan berasal dari fakta bahwa X mewarisi dari objek, tetapi Foo tidak. Apakah ada perbedaan lain yang timbul dari ini? Terima kasih.
— jeeyoungk

6
Ini tidak berfungsi untuk kelas gaya lama:, 'class Old:pass' 'isinstance(Old, type) == False'tapi inspect.isclass(Old) == True.
— jfs

1
@ jeeyoungk: Anda tidak "menganggap perbedaan berasal dari ...", Anda sebenarnya membaca itu dalam kode. Subclass objek ("gaya baru") memiliki properti yang diinginkan, seperti yang Anda lihat di sini.
— S.Lott

12
Inilah petunjuknya - karena ini berfungsi untuk kelas gaya baru, jangan gunakan kelas gaya lama. Tidak ada gunanya menggunakan kelas gaya lama.
— S.Lott

isinstance (e, f) E adalah objek instantiated, F adalah objek kelas.
— Dexter

24
isinstance(X, type)

Kembali Truejika Xkelas dan Falsejika tidak.


3
Saya mendapatkan False, bahkan jika X adalah kelas.
— Mads Skjern

6
Ini hanya berfungsi untuk kelas gaya baru. Kelas gaya lama adalah tipe 'classobj'. Jadi, jika Anda menggunakan kelas gaya lama yang dapat Anda lakukan: import types isinstance (X, types.ClassType)
— Charles L.

2
Ini tampaknya sama dengan S. Lott's answer, yaitu empat tahun lebih tua.
— Ethan Furman

5

Pemeriksaan ini kompatibel dengan Python 2.x dan Python 3.x.

import six
isinstance(obj, six.class_types)

Ini pada dasarnya adalah fungsi pembungkus yang melakukan pemeriksaan yang sama seperti pada jawaban andrea_crotti.

Contoh:

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


1

Cara paling sederhana adalah menggunakan inspect.isclasssebagaimana diposting dalam jawaban yang paling banyak dipilih.
detail implementasi dapat ditemukan di python2 inspect dan python3 inspect .
untuk kelas gaya baru: isinstance(object, type)
untuk kelas gaya lama: isinstance(object, types.ClassType)
em, untuk kelas gaya lama, yang digunakan types.ClassType, berikut adalah kode dari types.py :

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

1

Benjamin Peterson benar tentang penggunaan inspect.isclass()untuk pekerjaan ini. Tetapi perhatikan bahwa Anda dapat menguji apakah suatu Classobjek adalah spesifik Class, dan karenanya secara implisit a Class, menggunakan fungsi built-in issubclass . Tergantung pada kasus penggunaan Anda, ini bisa lebih pythonic.

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

Kemudian dapat digunakan seperti ini:

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

-2

Sudah ada beberapa solusi yang berfungsi di sini, tetapi ini satu lagi:

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

types.ClassTypetelah dihapus dengan Python 3
— Beau Barker
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.