简体   繁体   中英

Making a dynamic function from a string callable in Python?

My question is tied to Dan Bader's schedule package. From what I understand, you schedule function calls. That's pretty simple if you are defining the function in your script. However, what about functions that are built dynamically using exec()? Is there any way to make these callable? I keep getting errors when trying to schedule these functions. I recognize that this is likely not the best idea (maybe not even a good idea), but this is just for a POC and I'm still curious if this can be done.

def buildJob(lang, repType, name, file='', recipient='', server = '', db='', path=''):
    today = datetime.datetime.strftime(datetime.datetime.today(), '%m%d%Y%H%M%S')
    filePath = f"{c.path}{name}-{today}".replace('\\', '/')
    filename = f'{name}-{today}.xlsx'
    funcText = f"""
def {name}():
    sql = ("{file}")
    filePath = ("{filePath}")
    engine = sa.create_engine(conString)
    dat = pd.read_sql_query(sql, engine)
    engine.dispose()
    del engine
    buildSpreadsheet(dat, filePath)
    sendSpreadsheet("{recipient}", "{filePath}.xlsx", "{filename}")
        """

I then have a function to grab the funcText and exec() it. However, when I pass this into schedule, it says that the argument must be callable.

Any help would be greatly appreciated!

You can retrieve defined functions with the locals() and globals() dict s.

# in global scope
as_str = f"""
def foo():
    print('foo')
"""
exec(as_str)
foo = globals()['foo']
foo()

# in function scope
def bar():
   as_str = f"""
def baz():
    print('baz')
""" 
   exec(as_str)
   return locals()['baz']

baz = bar()
baz()

Someone may correct me but dynamic function creation with exec seems like a bad idea. Especially if the input isn't being sanitized.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM