getattr from local scope

R

rob.haswell

Hey there

My question is pretty simple - I want to use something like getattr to
grab a symbol from the local scope from a string.

Basically my application has a scheduler which stores names of
functions
defined in the "schedule" module in a database, to be run on certain
days.
Every night I call schedule.RunSchedule, which grabs all the rows on
the
database that have to be run now, and I want to call the function
defined
the same module according to that string.

I know I can use eval, but I've always been told that if you're using
eval, you're doing it wrong. Also not using eval limits the scope
damage
that can be caused by any errors in my application which could cause
the
database to be poisoned.

Cheers for any help :)

-Rob
 
E

Edward Elliott

Basically my application has a scheduler which stores names of functions
defined in the "schedule" module in a database, to be run on certain
days. Every night I call schedule.RunSchedule, which grabs all the rows on
the database that have to be run now, and I want to call the function
defined the same module according to that string.

I know that sys.modules[__name__] gives the module object for the current
module. You could do:

m = sys.modules[__name__] # M now current module object
func = m.__dict__ [fs] # func has function named by string fs
func()

If func isn't in the current module, replace __name__ with 'Foo'. Add
try/catch as appropriate in case fs doesn't exist in module M.

If your database stores the function arguments in the same string as the
function name, you'll have to parse them out separately.

I make no claims to this solution being optimal, as it pretty much
stretches my knowledge of Python modules and reflection.
 
A

Alex Martelli

Edward Elliott said:
Basically my application has a scheduler which stores names of functions
defined in the "schedule" module in a database, to be run on certain
days. Every night I call schedule.RunSchedule, which grabs all the rows on
the database that have to be run now, and I want to call the function
defined the same module according to that string.

I know that sys.modules[__name__] gives the module object for the current
module. You could do:

m = sys.modules[__name__] # M now current module object
func = m.__dict__ [fs] # func has function named by string fs
func()

sys.modules[__name__].__dict__ may be more handily accessed by the
built-in function globals().


Alex
 
E

Edward Elliott

Alex said:
sys.modules[__name__].__dict__ may be more handily accessed by the
built-in function globals().

Well there you go. Glad it's not that awkward.
 
F

Fredrik Lundh

I know I can use eval, but I've always been told that if you're using
eval, you're doing it wrong. Also not using eval limits the scope damage
that can be caused by any errors in my application which could cause
the database to be poisoned.

a more robust approach is to explicitly add public entry points to a
dictionary, and dispatch via that dictionary:

a simple decorator can be handy for this purpose:

registry = {}

def public(func):
registry[func.__name__] = func

@public
def func1():
print "func1"

@public
def func2():
print "func2"

def func3():
print "internal func3"

registry["func1"]()
registry["func3"]() # this will fail

in pre-decorator versions of python, this can be implemented either
by explicitly registering the entry points:

def func2():
print "func2"
public(func2)

or

def func2():
print "func2"
registry["func2"] = func2

or by using a prefix to make accidental publishing less likely:

def public_func2():
print "func2"

globals()["public_" + funcname]()

and/or by making all the callbacks methods of a class, and use getattr
on an instance of that class.

</F>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Forum statistics

Threads
474,294
Messages
2,571,511
Members
48,197
Latest member
ปั๊มเฟส|JoyLikeSEO

Latest Threads

Top