0

I have a string that contains a function name.

Using this string, how can I change the related function definition at run time?

This code updates the definition of the first function:

def first():
    print("first")
    
def second():
    print("second")
    
first = second

print(first)
print(second)

<function second at 0x7f35b40c3840>

<function second at 0x7f35b40c3840>

But that one doesn't:

def first():
    print("first")
    
def second():
    print("second")
    
func_to_change = "first"

eval_fist = eval(func_to_change)
exec('eval_fist = second')

print(eval_fist)
print(first)

<function second at 0x7f35b40c3a60>

<function first at 0x7f35b40c3840>

  • In the second code it doesn't look like you actually updated first, you only set `eval_first` equal to `first` in your code and then to `second` at runtime, the actual function `first` is not changed by your code. So `eval_first` correctly shows that it is function `second` and `first` is still first, unchanged. – Jeff Chen Oct 18 '21 at 15:18
  • note that approaches with `eval` on user input are *extremely dangerous* – 2e0byo Oct 18 '21 at 15:19
  • 3
    I'm not sure why you need `eval` and `exec` here. Functions are just objects. They are not different from variables. You can just assign a function's name to any other object you want. This seems like an XY-problem. Please try to give context of your ***real*** problem – Tomerikoo Oct 18 '21 at 15:27
  • Does this answer your question? [Using a string variable as a variable name (duplicate)](https://stackoverflow.com/q/11553721/6045800) – Tomerikoo Oct 18 '21 at 15:37
  • 1
    What, incidentally, are you trying to do? Monkeypatch an imported module? Have changed behaviour at runtime? What is the function *used* for? A more pythonic solution woud normally be to store a bunch of functions in a dict and then look up the right one, if all you want is to change which function gets called based on user input. – 2e0byo Oct 18 '21 at 15:42
  • @Tomerikoo thanks it worked! – malasteakin Oct 18 '21 at 15:58
  • Then mark the question as duplicate – Tomerikoo Oct 18 '21 at 16:02

1 Answers1

0
locals()[func_tochange] = second

or

exec(f'{func_tochange} = second')
nadapez
  • 2,603
  • 2
  • 20
  • 26
  • Apart from eval being bad, you can't use it like that. It will raise a syntax error. It's for expressions, not statements... – Tomerikoo Oct 18 '21 at 23:53
  • Sorry, I already corrected the code. Why is `eval` bad? It is a main feature of the language. I think it should be avoided when it is posibble, but not always is – nadapez Oct 19 '21 at 20:09
  • [Why is using 'eval' a bad practice?](https://stackoverflow.com/q/1832940/6045800) – Tomerikoo Oct 20 '21 at 08:29
  • I think eval can be used in a bad way. The main use of eval or exec is to evaluate code generated at runtime. And also it is not slow if it evaluates a previously compiled code. – nadapez Oct 21 '21 at 03:10