1

This is not a duplicate of creating a function object from a string because that is a Python 2 solution with exec not as a function()

Trying to implement that solution in Python 3 gets this:

d = {}
exec("def f(x): return x")in d
print(d)

returns:

{}

So the question is, how do I create a function in Python 3 from an arbitrary string? (In my case read in from a YAML file, but that's a side issue.)

Ray Salemi
  • 5,247
  • 4
  • 30
  • 63
  • 5
    I don't understand what the `in d` part is trying to do. If you just `exec` that code, you will be able to call `f(x)` in your code. Either way, I would never recommend running arbitrary strings, this seems like an XY problem – user3483203 Jul 18 '18 at 16:04
  • I need the function object so I can place it in an object to be used later. The use must be able to create an arbitrary function that uses data from the object. – Ray Salemi Jul 18 '18 at 16:05
  • @user3483203 that's part of the syntax of the `exec` keyword in Python 2 (apparently). It seems like a honkin' bad idea to me. – Adam Smith Jul 18 '18 at 16:05
  • Right. Understand that folks don't know my application. Moving beyond the question of whether others would do it, is it still possible to create a function object from an arbitrary string? – Ray Salemi Jul 18 '18 at 16:06
  • @RaySalemi "The user must be able to create an arbitrary function" You realize how dangerous that is, right? – Adam Smith Jul 18 '18 at 16:06
  • Yes I do. Thanks. That's not a problem in my application. – Ray Salemi Jul 18 '18 at 16:07
  • @RaySalemi hmm I guess I'm not imaginative enough to envision a use case where that danger is warranted ;) but I trust you've done your homework on that threat vector! – Adam Smith Jul 18 '18 at 16:08
  • It returns `{}` as it is not being called anywhere. (wrong info, ignore.) – sP_ Jul 18 '18 at 16:09
  • 1
    @sP_ No, it returns `{}` because `d` is an empty dictionary. The middle line of code just checks if `None` is a member of `d`, which it is not. – Adam Smith Jul 18 '18 at 16:11
  • @AdamSmith yes, this makes sense. – sP_ Jul 18 '18 at 16:12

2 Answers2

3

X in d , returns True if X is found in element d.

Your exec call is defining function f in global scope.

This appears to do what you want it to:

>>> d = {}
>>> exec("def f(x): return x", d)
>>> d["f"]("Hello World")
'Hello World'
Jake
  • 1,016
  • 8
  • 9
0
>>> d={}
>>> exec("def f(x): return x",None,d)
>>> d['f'](2)
2
>>>
blhsing
  • 91,368
  • 6
  • 71
  • 106