12

Code:

import types


class C(object):
    pass


c = C()
print(isinstance(c, types.InstanceType))

Output:

False

What correct way to check if object is instance of user-defined class for new-style classes?

UPD:

I want put additional emphasize on if checking if type of object is user-defined. According to docs:

types.InstanceType
The type of instances of user-defined classes.

UPD2:

Alright - not "correct" ways are OK too.

UPD3:

Also noticed that there is no type for set in module types

4
  • 1
    This is an odd need, what is it for? Commented Jan 30, 2013 at 21:04
  • Im trying to write a simple function to measure how much memory takes object provided as argument Commented Feb 2, 2013 at 6:10
  • Hmm, I still don't understand. Why do you need to know if it's a user-defined class? What will you do in the yes case that's different than the no case? Commented Feb 2, 2013 at 12:46
  • @NedBatchelder Probably it was __slots__ issue or something like that. Commented Nov 24, 2014 at 15:00

4 Answers 4

9
+100

You can combine the x.__class__ check with the presence (or not) of either '__dict__' in dir(x) or hasattr(x, '__slots__'), as a hacky way to distinguish between both new/old-style class and user/builtin object.

Actually, this exact same suggestions appears in https://stackoverflow.com/a/2654806/1832154

def is_instance_userdefined_and_newclass(inst):
    cls = inst.__class__
    if hasattr(cls, '__class__'):
        return ('__dict__' in dir(cls) or hasattr(cls, '__slots__'))
    return False

>>> class A: pass
... 
>>> class B(object): pass
... 
>>> a = A()
>>> b = B()
>>> is_instance_userdefined_and_newclass(1)
False
>>> is_instance_userdefined_and_newclass(a)
False
>>> is_instance_userdefined_and_newclass(b)
True
Sign up to request clarification or add additional context in comments.

6 Comments

Except that that will fail with objects defined in a c library. I guess the term hackish is appropriate.
@Antimony do you typically create (i.e. code) a class in a C library and load it while running a python code ? By user-defined I simply took that the user created it purely using Python, without relying on the CPython API with C code. And I'm aware this method can fail, but there is nothing else that works for the given question (your answer doesn't).
@mmgp Seems like this is the answer, thank you! I will wait 4 days more and accept/award your answer if no less hackish solutions will be posted.
Brilliant. I needed this today for precisely the same reason Gill needed this three years ago: memory profiling. When recursively profiling the space consumed by user-defined objects and the complete tree of user-defined referents those objects transitively refer to, recursion naturally bottoms out at built-in objects. This simple (albeit hackish) test just saved my Canadian bacon.
Relatedly, the last three lines of is_instance_userdefined_and_newclass() reduce to a single statement: return hasattr(cls, '__class__') and ('__dict__' in dir(cls) or hasattr(cls, '__slots__')). Negligible efficiency gains for the win.
|
7

I'm not sure about the "correct" way, but one easy way to test it is that instances of old style classes have the type 'instance' instead of their actual class.

So type(x) is x.__class__ or type(x) is not types.InstanceType should both work.

>>> class Old:
...     pass
...
>>> class New(object):
...     pass
...
>>> x = Old()
>>> y = New()
>>> type(x) is x.__class__
False
>>> type(y) is y.__class__
True
>>> type(x) is types.InstanceType
True
>>> type(y) is types.InstanceType
False

12 Comments

Beat me to it. I'll add the link in your answer, if you don't mind
Feel free to add the link.
Actually type(x) is x.__class__ returns True even if x = 1. So this way is not similar to isinstance(x, types.InstanceType)
@Gill that's because int is a new style class. Based on your actual edited question, it looks like you're out of luck.
|
1

This tells us True if it is.

if issubclass(checkthis, (object)) and 'a' not in vars(__builtins__):print"YES!"

The second argument is a tuple of the classes to be checked. This is easy to understand and i'm sure it works. [edit (object) to(object,) thanks Duncan!]

3 Comments

Your second argument is simply object. The parentheses don't magically turn it into a tuple: commas make tuples so (object,) would be a one element tuple. However in this case passing just object works fine because the second argument of issubclass() can be either a class or a tuple of things that issubclass() takes as its second argument. (Yes, the definition is recursive so you can use nested tuples of classes.)
issubclass(int, (object,)) also returns True and so doesn't do what the OP asked for.
Actually, the OP said 'not "correct" answers', which I understood to mean something that works even if it's not an official way. But I can see the confusion: downvote removed.
0

Probably I can go with elimination method - not checking if object is instance of user-defined class explicitly - isinstance(object, RightTypeAliasForThisCase), but checking if object not one of 'basic' types.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.