Làm thế nào để kiểm tra xem một biến có phải là một lớp hay không?


236

Tôi đã tự hỏi làm thế nào để kiểm tra xem một biến có phải là một lớp (không phải là một thể hiện!) Hay không.

Tôi đã cố gắng sử dụng chức năng isinstance(object, class_or_type_or_tuple)để làm điều này, nhưng tôi không biết một lớp sẽ có loại nào.

Ví dụ: trong đoạn mã sau

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

Tôi đã cố thay thế " class" bằng ??? , nhưng tôi nhận ra đó classlà một từ khóa trong python.

Câu trả lời:


334

Thậm chí tốt hơn: sử dụng inspect.isclasschức năng.

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

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

7
Nếu bạn cũng muốn inspect.isclassquay lại Truenếu đối tượng cần kiểm tra là một thể hiện của lớp , hãy sử dụnginspect.isclass(type(Myclass()))
michaelmeyer

8
Tốt hơn cái gì :)?
Nhà vật lý điên

8
@michaelmeyer type(whatever)luôn trả về một đối tượng là một lớp, vì vậy kiểm tra này là không cần thiết. Nếu không, sẽ không có cách nào để khởi tạo whatevervà do đó bạn không thể thực hiện kiểm tra ở nơi đầu tiên.
a_guest

Không làm việc cho tôi. Sử dụng python3 với snakemake, type(snakemake.utils)trả về <class 'module'>inspect.isclass(snakemake.utils)trả về False.
tedtoal

3
Đó là bởi vì snakemake.utilmột mô-đun không phải là một lớp học?
Benjamin Peterson

44

Kiểm tra có thể là giải pháp tốt nhất và thật dễ dàng để xem cách nó thực sự được thực hiện

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
nhớimport types
nguyên

13
types.ClassTypekhông còn cần thiết trong Python 3 (và đã bị xóa).
kawing-chiu

điều này hoàn toàn không hoạt động với các lớp phong cách mới .... ngay cả trong python 2. không sử dụng giải pháp này một mình
Erik Aronesty

Nó được lấy từ mô-đun kiểm tra nên tôi nghi ngờ nó không hoạt động. Thật đơn giản để kiểm tra với Python2.7 chẳng hạnIn [8]: class NewStyle(object): ...: pass ...: In [9]: isinstance(NewStyle, (type, types.ClassType)) Out[9]: True
andrea_crotti

Đây là triển khai Python 2, phải xử lý các lớp kiểu cũ và kiểu mới. Python 3 đơn giản hóa điều này thành isinstance(object, type). Lưu ý rằng đối tượng thích int, list, str, vv là cũng lớp, vì vậy bạn không thể sử dụng để phân biệt giữa các lớp học tùy chỉnh được xác định bằng Pythonbuilt-in lớp được định nghĩa trong mã C .
Martijn Pieters

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

1
Hừm ... Câu trả lời hay, nhưng khi tôi gõ (Foo) trên lớp Foo của mình, nó nói <type 'classobj'> thay vì <type 'type'>. Tôi cho rằng sự khác biệt xuất phát từ thực tế là X đang thừa hưởng từ đối tượng, nhưng Foo thì không. Có sự khác biệt nào khác phát sinh từ điều này? Cảm ơn.
jeeyoungk

6
Nó không hoạt động cho các lớp kiểu cũ : 'class Old:pass' 'isinstance(Old, type) == False', nhưng inspect.isclass(Old) == True.
JFS

1
@jeeyoungk: Bạn không "giả sử sự khác biệt đến từ ...", bạn thực sự đang đọc mã đó. Một lớp con của đối tượng ("kiểu mới") có các thuộc tính mong muốn, giống như những gì bạn thấy ở đây.
S.Lott

12
Đây là gợi ý - vì cách này hoạt động cho các lớp kiểu mới, không sử dụng các lớp kiểu cũ. Không có điểm nào để sử dụng các lớp kiểu cũ.
S.Lott

isinstance (e, f) E là đối tượng khởi tạo, F là đối tượng lớp.
Dexter

24
isinstance(X, type)

Trả về Truenếu Xlà lớp và Falsenếu không.


3
Tôi nhận được Sai, ngay cả khi X là một lớp.
Mads Skjern

6
Điều này chỉ hoạt động cho các lớp phong cách mới. Các lớp kiểu cũ là loại 'classobj'. Vì vậy, nếu bạn đang sử dụng các lớp kiểu cũ, bạn có thể thực hiện: nhập kiểu isinstance (X, type.ClassType)
Charles L.

2
Điều này dường như giống như S. Lott's answer, hơn bốn tuổi.
Ethan Furman

5

Kiểm tra này tương thích với cả Python 2.x và Python 3.x.

import six
isinstance(obj, six.class_types)

Về cơ bản, đây là một hàm bao bọc thực hiện kiểm tra giống như trong câu trả lời của andrea_crotti.

Thí dụ:

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


1

cách đơn giản nhất là sử dụng inspect.isclassnhư được đăng trong câu trả lời được bình chọn nhiều nhất.
các chi tiết thực hiện có thể được tìm thấy tại python2 testspython3 tests .
đối với lớp kiểu mới: isinstance(object, type)
đối với lớp kiểu cũ: isinstance(object, types.ClassType)
em, đối với lớp kiểu cũ, nó đang sử dụng types.ClassType, đây là mã từ type.py :

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

1

Benjamin Peterson là chính xác về việc sử dụng inspect.isclass()cho công việc này. Nhưng lưu ý rằng bạn có thể kiểm tra nếu một Classđối tượng là một cụ thể Class, và do đó mặc nhiên một Class, bằng cách sử dụng built-in chức năng issubclass . Tùy thuộc vào trường hợp sử dụng của bạn, điều này có thể nhiều pythonic.

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

Sau đó có thể được sử dụng như thế này:

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

-2

Có một số giải pháp làm việc ở đây, nhưng đây là một giải pháp khác:

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

types.ClassTypeđã bị xóa trong Python 3
Beau Barker
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.