check to see if a symbol in a string has a binding

Alex Martelli aleax at aleax.it
Thu Apr 17 17:10:29 CEST 2003


Jinsong Zhao wrote:

> Sorry if the question is too simple. I want to see if the name inside
> the string has a binding and callable. For example,
> 
> 1. func_string="func"
> 2. func_string="func_string"
> 3. func_string="dir"
> 
> So the in case 1, "func" does not have a binding; case 2 "func_string"
> has a binding but not callable; in case 3 "dir" has a binding and is
> callable. How do I proceed based on the content in func_string? This
> is rather baffling.

It IS a rather weird specification, yes -- to look for a binding
ANYwhere, whether it be in the current function's locals, in the
current module's globals, or in the builtins?!  Why would one
ever want to do something like that...?

Anyway, first of all, you want the string's content to be "a
name": you can check that with modules cStringIO, tokenize,
and keyword -- perhaps overkill, but that *ensures* you're 
using the same rules Python itself uses to define what's 
a 'name'...:

import cStringIO, tokenize, keyword

def isaname(s):
    toks=list(tokenize.generate_tokens(cStringIO.StringIO(s).readline))
    if len(toks)!=2: return False
    if tokenize.tok_name[toks[0][0]] != 'NAME': return False
    return not keyword.iskkeyword(s)


Once you DO know s is a name, you can then safely try to evaluate
it as an expression, catching any possible errors, and check if 
the resulting value is callable.

So, overall:

def checkJZ(s):
    if not isaname(s): return False
    try: obj = eval(s)
    except NameError: return False
    else: return callable(obj)

So, does this meet your peculiar specs...?


Alex





More information about the Python-list mailing list