How to get the value of a variable given its name in a string?
If it's a global variable, then you can do:
>>> a = 5
>>> globals()['a']
5
A note about the various "eval" solutions: you should be careful with eval, especially if the string you're evaluating comes from a potentially untrusted source -- otherwise, you might end up deleting the entire contents of your disk or something like that if you're given a malicious string.
(If it's not global, then you'll need access to whatever namespace it's defined in. If you don't have that, there's no way you'll be able to access it.)
Getting the name of a variable as a string
TL;DR
Use the Wrapper
helper from python-varname
:
from varname.helpers import Wrapper
foo = Wrapper(dict())
# foo.name == 'foo'
# foo.value == {}
foo.value['bar'] = 2
For list comprehension part, you can do:
n_jobs = Wrapper(<original_value>)
users = Wrapper(<original_value>)
queues = Wrapper(<original_value>)
priorities = Wrapper(<original_value>)
list_of_dicts = [n_jobs, users, queues, priorities]
columns = [d.name for d in list_of_dicts]
# ['n_jobs', 'users', 'queues', 'priorities']
# REMEMBER that you have to access the <original_value> by d.value
I am the author of the python-varname
package. Please let me know if you have any questions or you can submit issues on Github.
The long answer
Is it even possible?
Yes and No.
We are retrieving the variable names at runtime, so we need a function to be called to enable us to access the previous frames to retrieve the variable names. That's why we need a Wrapper
there. In that function, at runtime, we are parsing the source code/AST nodes in the previous frames to get the exact variable name.
However, the source code/AST nodes in the previous frames are not always available, or they could be modified by other environments (e.g: pytest
's assert
statement). One simple example is that the codes run via exec()
. Even though we are still able to retrieve some information from the bytecode, it needs too much effort and it is also error-prone.
How to do it?
First of all, we need to identify which frame the variable is given. It's not always simply the direct previous frame. For example, we may have another wrapper for the function:
from varname import varname
def func():
return varname()
def wrapped():
return func()
x = wrapped()
In the above example, we have to skip the frame inside wrapped
to get to the right frame x = wrapped()
so that we are able to locate x
. The arguments frame
and ignore
of varname
allow us to skip some of these intermediate frames. See more details in the README file and the API docs of the package.
Then we need to parse the AST node to locate where the variable is assigned value (function call) to. It's not always just a simple assignment. Sometimes there could be complex AST nodes, for example, x = [wrapped()]
. We need to identify the correct assignment by traversing the AST tree.
How reliable is it?
Once we identify the assignment node, it is reliable.
varname
is all depending on executing
package to look for the node. The node executing detects is ensured to be the correct one (see also this).
It partially works with environments where other AST magics apply, including pytest, ipython, macropy, birdseye, reticulate with R, etc. Neither executing nor varname is 100% working with those environments.
Do we need a package to do it?
Well, yes and no, again.
If your scenario is simple, the code provided by @juan Isaza or @scohe001 probably is enough for you to work with the case where a variable is defined at the direct previous frame and the AST node is a simple assignment. You just need to go one frame back and retrieve the information there.
However, if the scenario becomes complicated, or we need to adopt different application scenarios, you probably need a package like python-varname
, to handle them. These scenarios may include to:
- present more friendly messages when the source code is not available or AST nodes are not accessible
- skip intermediate frames (allows the function to be wrapped or called in other intermediate frames)
- automatically ignores calls from built-in functions or libraries. For example:
x = str(func())
- retrieve multiple variable names on the left-hand side of the assignment
- etc.
How about the f-string
?
Like the answer provided by @Aivar Paalberg. It's definitely fast and reliable. However, it's not at runtime, meaning that you have to know it's foo
before you print the name out. But with varname
, you don't have to know that variable is coming:
from varname import varname
def func():
return varname()
# In external uses
x = func() # 'x'
y = func() # 'y'
Finally
python-varname
is not only able to detect the variable name from an assignment, but also:
- Retrieve variable names directly, using
nameof
- Detect next immediate attribute name, using
will
- Fetch argument names/sources passed to a function using
argname
Read more from its documentation.
However, the final word I want to say is that, try to avoid using it whenever you can.
Because you can't make sure that the client code will run in an environment where the source node is available or AST node is accessible. And of course, it costs resources to parse the source code, identify the environment, retrieve the AST nodes and evaluate them when needed.
How to get value from List<> giving String as variable name
You need a Map<String, Function<Contact, String>>
containing method references, keyed by the property name.
For example:
// Construct this once, store in a static final field.
Map<String, Function<Contact, String> map =
Map.of("name", c -> c.name /* etc for other fields */);
// Then, when you want to get the value:
String val = map.get(var).apply(contactList.get(0));
How to use string value as a variable name in Python?
I don't understand what exactly you're trying to achieve by doing this but this can be done using eval
. I don't recommend using eval
though. It'd be better if you tell us what you're trying to achieve finally.
>>> candy = ['a','b','c']
>>> fruit = ['d','e','f']
>>> snack = ['g','h','i']
>>> name = 'fruit'
>>> eval(name)
['d', 'e', 'f']
EDIT
Look at the other answer by Sнаđошƒаӽ. It'll be better way to go. eval
has security risk and I do not recommend its usage.
How to get a variable value if variable name is stored as string?
You can use ${!a}
:
var1="this is the real value"
a="var1"
echo "${!a}" # outputs 'this is the real value'
This is an example of indirect parameter expansion:
The basic form of parameter expansion is
${parameter}
. The value of
parameter
is substituted.If the first character of
parameter
is an exclamation point (!), it
introduces a level of variable indirection. Bash uses the value of the
variable formed from the rest ofparameter
as the name of the
variable; this variable is then expanded and that value is used in the
rest of the substitution, rather than the value ofparameter
itself.
Get variable by name from a String
Using reflection doesn't seem like a good design for what you're doing here. It would be better to use a Map<String, Integer>
for example:
static final Map<String, Integer> VALUES_BY_NAME;
static {
final Map<String, Integer> valuesByName = new HashMap<>();
valuesByName.put("width", 5);
valuesByName.put("potato", 2);
VALUES_BY_NAME = Collections.unmodifiableMap(valuesByName);
}
Or with Guava:
static final ImmutableMap<String, Integer> VALUES_BY_NAME = ImmutableMap.of(
"width", 5,
"potato", 2
);
Or with an enum:
enum NameValuePair {
WIDTH("width", 5),
POTATO("potato", 2);
private final String name;
private final int value;
private NameValuePair(final String name, final int value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
static NameValuePair getByName(final String name) {
for (final NameValuePair nvp : values()) {
if (nvp.getName().equals(name)) {
return nvp;
}
}
throw new IllegalArgumentException("Invalid name: " + name);
}
}
Variable name as a string in Javascript
Typically, you would use a hash table for a situation where you want to map a name to some value, and be able to retrieve both.
var obj = { myFirstName: 'John' };obj.foo = 'Another name';for(key in obj) console.log(key + ': ' + obj[key]);
How to get a variable name as a string in PHP?
You could use get_defined_vars() to find the name of a variable that has the same value as the one you're trying to find the name of. Obviously this will not always work, since different variables often have the same values, but it's the only way I can think of to do this.
Edit: get_defined_vars() doesn't seem to be working correctly, it returns 'var' because $var is used in the function itself. $GLOBALS seems to work so I've changed it to that.
function print_var_name($var) {
foreach($GLOBALS as $var_name => $value) {
if ($value === $var) {
return $var_name;
}
}
return false;
}
Edit: to be clear, there is no good way to do this in PHP, which is probably because you shouldn't have to do it. There are probably better ways of doing what you're trying to do.
Change the value of a variable given its name in a string
>>> a2b2 = 2
>>> a3b3 = 2
>>> a4b4 = 2
>>> a5b5 = 2
>>> for i in range(2, 6):
... exec(f"a{i}b{i} = {i*3}")
...
>>> a2b2
6
>>> a3b3
9
>>> a4b4
12
>>> a5b5
15
You can do like this.
Related Topics
Why Is Python Running My Module When I Import It, and How to Stop It
Delete a Column from a Pandas Dataframe
Permanently Add a Directory to Pythonpath
Catch Multiple Exceptions in One Line (Except Block)
How to Check Which Version of Python Is Running My Script
Python Requests Throwing Sslerror
Changing One Character in a String
Difference Between Map, Applymap and Apply Methods in Pandas
Typeerror: Method() Takes 1 Positional Argument But 2 Were Given
Display Number With Leading Zeros
List Comprehension on a Nested List
How to Use Raw_Input in Python 3
Variable Scopes in Python Classes
Numpy 'Logical_Or' For More Than Two Arguments