[Python-Dev] operator.is*Type (original) (raw)

Michael Foord fuzzyman at voidspace.org.uk
Wed Feb 22 22:00:57 CET 2006


Raymond Hettinger wrote:

[Ian Bicking]

They seem terribly pointless to me. FWIW, here is the script that had I used while updating and improving the two functions (can't remember whether it was for Py2.3 or Py2.4). It lists comparative results for many different types of inputs. Since perfection was not possible, the goal was to have no false negatives and mostly accurate positives. IMO, they do a pretty good job and are able to access information in not otherwise visable to pure Python code. With respect to user defined instances, I don't care that they can't draw a distinction where none exists in the first place -- at some point you have to either fallback on duck-typing or be in control of what kind of arguments you submit to your functions. Practicality beats purity -- especially when a pure solution doesn't exist (i.e. given a user defined class that defines just getitem, both mapping or sequence behavior is a possibility). But given :

True True Instance w getitem <type 'instance'> True True NewStyle Instance w getitem <class '__main__.cng'> True True [] <class UserList.UserList at 0x00F11B70> True True {} <type 'instance'>

(Last one is UserDict)

I can't conceive of circumstances where this is useful without duck typing as well.

The tests seem roughly analogous to :

def isMappingType(obj): return isinstance(obj, dict) or hasattr(obj, 'getitem')

def isSequenceType(obj): return isinstance(obj, (basestring, list, tuple, collections.deque)) or hasattr(obj, 'getitem')

If you want to allow sequence access you could either just use the isinstance or you have to trap an exception in the case of a mapping object being passed in.

Redefining (effectively) as :

def isMappingType(obj): return isinstance(obj, dict) or (hasattr(obj, 'getitem') and hasattr(obj, 'keys'))

def isSequenceType(obj): return isinstance(obj, (basestring, list, tuple, collections.deque)) or (hasattr(obj, 'getitem') and not hasattr(obj, 'keys'))

Makes the test useful where you want to know you can safely treat an object as a mapping (or sequence) and where you want to tell the difference.

The only code that would break is use of mapping objects that don't define keys and sequences that do. I imagine these must be very rare and would be interested in seeing real code that does break. Especially if that code cannot be trivially rewritten to use the first example.

All the best,

Michael Foord

---- Analysis Script ---- from collections import deque from UserList import UserList from UserDict import UserDict from operator import * types = (set, int, float, complex, long, bool, str, unicode, list, UserList, tuple, deque, ) for t in types: print isMappingType(t()), isSequenceType(t()), repr(t()), repr(t) class c: def repr(self): return 'Instance w/o getitem' class cn(object): def repr(self): return 'NewStyle Instance w/o getitem' class cg: def repr(self): return 'Instance w getitem' def getitem(self): return 10 class cng(object): def repr(self): return 'NewStyle Instance w getitem' def getitem(self): return 10 def f(): return 1 def g(): yield 1 for i in (None, NotImplemented, g(), c(), cn()): print isMappingType(i), isSequenceType(i), repr(i), type(i) for i in (cg(), cng(), dict(), UserDict()): print isMappingType(i), isSequenceType(i), repr(i), type(i)

---- Output ---- False False set([]) <type 'set'> False False 0 <type 'int'> False False 0.0 <type 'float'> False False 0j <type 'complex'> False False 0L <type 'long'> False False False <type 'bool'> False True '' <type 'str'> False True u'' <type 'unicode'> False True [] <type 'list'> True True [] <class UserList.UserList at 0x00F11B70> False True () <type 'tuple'> False True deque([]) <type 'collections.deque'> False False None <type 'NoneType'> False False NotImplemented <type 'NotImplementedType'> False False <generator object at 0x00F230A8> <type 'generator'> False False Instance w/o getitem <type 'instance'> False False NewStyle Instance w/o getitem <class '_main_.cn'> True True Instance w getitem <type 'instance'> True True NewStyle Instance w getitem <class '_main_.cng'> True False {} <type 'dict'> True True {} <type 'instance'>



More information about the Python-Dev mailing list