Como verificar se uma variável é uma classe ou não?


236

Eu queria saber como verificar se uma variável é uma classe (não uma instância!) Ou não.

Eu tentei usar a função isinstance(object, class_or_type_or_tuple)para fazer isso, mas não sei que tipo uma classe terá.

Por exemplo, no código a seguir

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

Eu tentei substituir " class" por ??? , mas percebi que classé uma palavra-chave em python.

Respostas:


335

Melhor ainda: use a inspect.isclassfunção

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

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

7
Se você também quiser inspect.isclassa devolução Truese o objeto para inspecionar é uma instância de classe , o usoinspect.isclass(type(Myclass()))
michaelmeyer

8
Melhor do que o que :)?
Mad Physicist

8
@michaelmeyer type(whatever)sempre retorna um objeto que é uma classe, portanto essa verificação é redundante. Caso contrário, não haveria maneira de instanciar whatevere, portanto, você não poderia executar a verificação em primeiro lugar.
a_guest

Não funciona para mim. Usando python3 com snakemake, type(snakemake.utils)retorna <class 'module'>e ainda inspect.isclass(snakemake.utils)retorna False.
tedtoal

3
Isso porque snakemake.utilum módulo não é uma classe?
Benjamin Peterson

44

A inspect.isclass é provavelmente a melhor solução e é realmente fácil ver como ela é realmente implementada

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
lembre-seimport types
nguyên

13
types.ClassTypenão é mais necessário no Python 3 (e é removido).
Kawing-chiu 8/03/16

Isso não funciona com as novas classes de estilo em tudo .... mesmo em python 2. uso não faça esta solução por si só
Erik Aronesty

Isso foi retirado do módulo de inspeção, então duvido que não funcione. É simples verificar com o Python2.7, por exemploIn [8]: class NewStyle(object): ...: pass ...: In [9]: isinstance(NewStyle, (type, types.ClassType)) Out[9]: True
andrea_crotti

Esta é a implementação do Python 2, que precisa lidar com classes de estilo antigo e novo. O Python 3 simplifica isso para isinstance(object, type). Note-se que objetos como int, list, str, etc, são também as classes, para que você não pode usar isso para distinguir entre classes personalizadas definidas em Python e built-in classes definidas no código C .
Martijn Pieters

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

1
Hum ... Boa resposta, mas quando eu digito (Foo) na minha classe Foo, ele diz <type 'classobj'> em vez de <type 'type'>. Suponho que a diferença vem do fato de que X é herdado do objeto, mas Foo não. Existe alguma outra diferença decorrente disso? Obrigado.
jeeyoungk

6
Não funciona para aulas de estilo antigo:, 'class Old:pass' 'isinstance(Old, type) == False'mas inspect.isclass(Old) == True.
JFS

1
@jeeyoungk: Você não está "assumindo que a diferença vem de ...", na verdade está lendo isso no código. Uma subclasse de objeto ("novo estilo") tem as propriedades desejadas, exatamente o que você vê aqui.
315/08 S.Lott

12
Aqui está a dica - como isso funciona para classes de novo estilo, não use classes de estilo antigo. Não faz sentido usar classes de estilo antigo.
315/08 S.Lott

isinstance (e, f) E é o objeto instanciado, F é o objeto de classe.
Dexter

24
isinstance(X, type)

Retorne Truese Xfor classe e Falsese não for.


3
Fico falso, mesmo que X seja uma classe.
Mads Skjern

6
Isso funciona apenas para novas classes de estilo. As classes de estilo antigo são do tipo 'classobj'. Então, se você estiver usando as classes de estilo antigo que você pode fazer: tipos de importação isinstance (X, types.ClassType)
Charles L.

2
Parece ser o mesmo que S. Lott's answer, quatro anos mais velho.
Ethan Furman 10/10

5

Essa verificação é compatível com o Python 2.xe o Python 3.x.

import six
isinstance(obj, six.class_types)

Essa é basicamente uma função de wrapper que executa a mesma verificação que na resposta andrea_crotti.

Exemplo:

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


1

A maneira mais simples é usar inspect.isclasscomo postado na resposta mais votada.
os detalhes da implementação podem ser encontrados em python2 inspecionar e python3 inspecionar .
para classe de estilo novo: isinstance(object, type)
para classe de estilo antigo: isinstance(object, types.ClassType)
em, para classe de estilo antigo, está usando types.ClassType, aqui está o código de types.py :

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

1

Benjamin Peterson está correto sobre o uso de inspect.isclass()para este trabalho. Mas observe que você pode testar se um Classobjeto é um específico Classe, portanto, implicitamente a Class, usando a função interna issubclass . Dependendo do seu caso de uso, isso pode ser mais pitônico.

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

Pode então ser usado assim:

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

-2

Já existem algumas soluções de trabalho aqui, mas aqui está outra:

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

types.ClassTypefoi removido em Python 3
Beau Barker
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.