0
var = {'hello': 'world', 'good': 'day', 'see': 'you'}

Function:

def func(key):
    return newfunc(var[key])

I would like to get something like this: hello = func('hello') = newfunc('world').

varlist = list(var.keys())
for i, variab in enumerate(varlist):
    varname = variab
    variab = func(varname)

But the problem at last the variables are not defined because the variable variab is overwritten when the next iteration starts. So do I have other ways to code a for loop to define all the variables in the dict?

I know I can keep writing hello = func('hello') and other variables every line but I would like to know if another method is possible.

martineau
  • 119,623
  • 25
  • 170
  • 301
  • Suggest you read [**_Why you don't want to dynamically create variables_**](http://stupidpythonideas.blogspot.com/2013/05/why-you-dont-want-to-dynamically-create.html). – martineau Sep 19 '17 at 15:18
  • You should have a look at: https://stackoverflow.com/a/11553741/7740201 This solution seems to work – DFE Sep 19 '17 at 15:19

4 Answers4

2

You may find this article to be a worthwhile read: http://stupidpythonideas.blogspot.com/2013/05/why-you-dont-want-to-dynamically-create.html/

The short answer to the problem is that when you do:

variab = func(varname)

You aren't defining a new variable, you are just defining the value stored in the variable. Variab is static. The name isnt changing. To define a static variable, you use the syntax

globlas()[variablename] = variablevalue

And while this is possible, it begs the question of why? There is pretty much no need to create variables dynamically in this way, and there's a reason why you don't generally see this pattern in programming. The solution? Use a data structure to solve the problem properly.

The article suggests dictionaries, but depending on your data structure you can use classes as well. It depends on the problem you are trying to accomplish.

If you must use dynamically created global variables I would strongly recommend getting past the new to Python stage before doing so. Again, the current code patterns and data structures exist for a reason, and I would discourage willingly avoiding them in favor of a workaround style solution.

Brandon Barney
  • 2,382
  • 1
  • 9
  • 18
  • Thank you for your reply! I am doing python scripting project in a metrology software. I intend to create variables for each points and axises on the component, so it's easier to write new functions based on those variables but not the given 'functions' in the software. The point in the software is not defined as a variable but like this : project.inspection['Point 1'] – Willnil Phoon Sep 20 '17 at 09:02
  • Then it sounds like you want to store your variables in a dictionary so that you can call upon those variables afterward. The idea is that you are storing the returned values in an organized structure that allows you to access them as needed. – Brandon Barney Sep 20 '17 at 11:16
0

Dynamically creating variables can be done, but it is not wise. Maintenance is a nightmare. It would be better to store the functions in a dictionary with the key value being what the dynamically created variable would have been. This should give you an idea of how it can be done:

#!/usr/bin/python

h = {'hello': 'world', 'good': 'day', 'see': 'you' }
def func(v):
    def newfunc():
        return v
    return newfunc

for k,v in h.items():
    h[k] = func(v)

a = h['hello']()
b = h['good']()
c = h['see']()

print("a = {}".format(a))
print("b = {}".format(b))
print("c = {}".format(c))
David Jenkins
  • 461
  • 3
  • 8
0

First of all, are those values callable functions or just string values?

If they are some callable functions, something like:

a = {'hello': hello, 'world': world}

It is simple and straight forward:

A = {'hello': hello, 'world': world}

def foo(var):
    callback = A.get(var, None)

    # You cancheck and raise when the value
    # is not a method.
    if not callable(callback):
        raise

    return callback

foo('hello')
0

You can put the variable, fn pairs in a dict. Also some comments:

  • you don't use the index i in the for loop so there is no point in using enumerate.
  • there is no point renaming variab to varname. If you want to use this name then just use it from the beginning.
  • you can iterate the dict_keys so there is no need for the varlist = list(var.keys()) line, you can just use for variab in var.keys()...
  • ... actually you don't even need the var.keys(). for key in dictionary iterates through the keys of the dictionary, so you can just use for variab in var.

So something like this would work: fn_dict = {} for varname in var: fn_dict[varname] = func(varname)

At the end of the loop you will have the fn_dict populated with the key, function pairs you want.