จะตรวจสอบว่าตัวแปรเป็นคลาสได้หรือไม่?


236

ฉันสงสัยว่าจะตรวจสอบได้อย่างไรว่าตัวแปรเป็นคลาส (ไม่ใช่อินสแตนซ์!) หรือไม่

ฉันพยายามใช้ฟังก์ชั่นisinstance(object, class_or_type_or_tuple)การทำเช่นนี้ แต่ฉันไม่ทราบว่าชั้นเรียนจะมีประเภทใด

ตัวอย่างเช่นในรหัสต่อไปนี้

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

ฉันพยายามแทนที่ " class" ด้วย??? แต่ฉันรู้ว่าclassเป็นคำหลักในหลาม

คำตอบ:


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โมดูลไม่ได้เรียนหรือไม่
Benjamin Peterson

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
เหงียน

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ฯลฯนอกจากนี้ยังมีการเรียนดังนั้นคุณจึงไม่สามารถใช้เพื่อแยกความแตกต่างระหว่างการเรียนที่กำหนดเองที่กำหนดไว้ในหลามและสร้างขึ้นในชั้นเรียนที่กำหนดไว้ในรหัส 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: คุณไม่ได้ "สมมติว่าความแตกต่างมาจาก ... " คุณจริง ๆ แล้วอ่านในรหัส คลาสย่อยของวัตถุ ("รูปแบบใหม่") มีคุณสมบัติที่ต้องการเพียงแค่สิ่งที่คุณเห็นที่นี่
S.Lott

12
นี่คือคำใบ้ - เนื่องจากสิ่งนี้ใช้ได้กับคลาสแบบใหม่อย่าใช้คลาสแบบเก่า ไม่มีประโยชน์ในการใช้คลาสเก่า
S.Lott

isinstance (e, f) E เป็นวัตถุที่สร้างอินสแตนซ์ F เป็นวัตถุคลาส
เด็กซ์เตอร์

24
isinstance(X, type)

ส่งคืนTrueถ้าXเป็นคลาสและFalseถ้าไม่


3
ฉันเข้าใจผิดถึงแม้ว่า X จะเป็นคลาส
Mads Skjern

6
ใช้งานได้กับคลาสสไตล์ใหม่เท่านั้น คลาสสไตล์เก่าเป็นประเภท 'classobj' ดังนั้นถ้าคุณกำลังใช้คลาสสไตล์เก่าคุณสามารถทำได้: import types isinstance (X, types.ClassType)
Charles L.

2
สิ่งนี้ดูเหมือนจะเหมือนกันS. Lott's answerซึ่งมีอายุมากกว่าสี่ปี
Ethan Furman

5

การตรวจสอบนี้เข้ากันได้กับทั้ง Python 2.x และ Python 3.x

import six
isinstance(obj, six.class_types)

นี่เป็นฟังก์ชั่น wrapper ที่ทำหน้าที่ตรวจสอบเช่นเดียวกับในคำตอบ andrea_crotti

ตัวอย่าง:

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

1

class Foo: เรียกว่า class style แบบเก่าและ class X (object): เรียกว่า class style ใหม่

เลือกสิ่งนี้ความแตกต่างระหว่างสไตล์เก่ากับคลาสสไตล์ใหม่ใน Python คืออะไร . แนะนำรูปแบบใหม่ อ่านเกี่ยวกับ " ประเภทและคลาสที่รวมกัน "


6
นี่น่าจะเป็นความเห็นใช่มั้ย
Kos

1

วิธีที่ง่ายที่สุดคือใช้inspect.isclassเป็นคำตอบที่ได้รับการโหวตมากที่สุด
รายละเอียดการดำเนินงานที่อาจจะพบได้ที่python2 ตรวจสอบและpython3 ตรวจสอบ
สำหรับคลาสแบบใหม่: isinstance(object, type)
สำหรับคลาสแบบเก่า: isinstance(object, types.ClassType)
em, สำหรับคลาสแบบเก่าที่ใช้types.ClassTypeอยู่นี่คือรหัสจากtypes.py :

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

1

Benjamin Peterson ถูกต้องเกี่ยวกับการใช้inspect.isclass()งานนี้ แต่โปรดทราบว่าคุณสามารถทดสอบว่าClassวัตถุนั้นมีความเฉพาะเจาะจงClassหรือไม่และโดยปริยาย a Classโดยใช้ฟังก์ชันissubclass ในตัว ขึ้นอยู่กับการใช้งานของคุณกรณีนี้สามารถ pythonic เพิ่มเติม

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.