From: mal at lemburg.com (M.-A. Lemburg)
Date: Sat, 03 Apr 1999 10:59:36 +0200
Subject: add type predicates to types module?
References: <cr1EjogB0KGWMPCmVY@holmes.parc.xerox.com> <14085.18842.492142.484721@bitdiddle.cnri.reston.va.us>
Message-ID: <3705D878.4454DBEB@lemburg.com>
Content-Length: 2384
X-UID: 1476                                                  

Jeremy Hylton wrote:
> 
> This is a really good idea.  I know I've got type predicates of many
> different flavors in code I've been working on recently.  The tough
> question, I think, is how to decide which predicates are needed and
> how to implement them.
> 
> The folkloric "file-like object" type is a good example.  When people
> say "file-like object" they mean an object that responds in a
> reasonable way to the particular subset of methods on a builtin file
> object that they are interested in.
> 
> isSequence might be a better example, since you want to capture
> instances that implement the sequence protocol along with tuples,
> lists, and strings.  I use:
> 
> def isSequence(s):
>     try:
>         0 in s
>     except TypeError:
>         return 0
>     else:
>         return 1

I tried this a while back but then concluded that the meaning
of "is sequence" can mean different things in different situations,
e.g. sometimes I need the object to have a length, at other times
I need __getitem__ (this is what "in" uses).

Note that the above test fails for dictionary types, but let's
dictionary like instances pass.

I think a more generic API is needed; one that allows you to
define the slots/special methods you really need (we'd have to
map the special methods to slots for simplicity). Something
like
	has_interface(obj,('__getitem__','__len__'))

> def isCallable(obj):
>     if type(obj) in (types.BuiltinFunctionType,
>                      types.BuiltinMethodType,  types.LambdaType,
>                      types.MethodType):
>         # XXX could include types.UnboundMethodType
>         return 1
>     if type(obj) == types.InstanceType:
>         return hasattr(obj, '__call__')
>     return 0

There already is a builtin function iscallable() that does pretty
much what you've coded in Python.

> In the particular application I needed, I know I would not want to
> include UnboundMethodTypes.  In the general case, though, I think it
> should be included.

... this is a special case I guess. iscallable(obj) and a type
check could be combined to handle it.

-- 
Marc-Andre Lemburg                               Y2000: 272 days left
---------------------------------------------------------------------
          : Python Pages >>> http://starship.skyport.net/~lemburg/  :
           ---------------------------------------------------------





