Python Forum

Full Version: How create programmatically variables ?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi everyone,

I would like to create programmatically / automatically some variable inside a function...

I've dig the WWW but I found only very old results that lead to create some Dictionary...

Is my wish possible in Python ?

Thanks.
(Aug-09-2023, 04:11 AM)SpongeB0B Wrote: [ -> ]I've dig the WWW but I found only very old results that lead to create some Dictionary...
Variables in Python are kept in namespaces, which have a dictionary-like semantics. For example global variables in a module are kept in the globals() dictionary, which you could also access as vars(sys.modules[__name__]). You can update these dictionaries to create module-level variables.

Usually however, this is bad practice and it is better to use another dictionary that your program creates.

I see a good use case for this, which is lazy imports of subpackages in a package Spam:
# Spam.__init__.py

def __getattr__(name):
    from importlib import import_module
    submodule = import_module(name, __package__)
    globals()[name] = submodule
    return submodule
Now in client code
import Spam
# accessing Spam.eggs automatically imports submodule Spam.eggs
Spam.eggs.somefunction()

# on second access, nothing is imported because eggs is now a member of Spam
Spam.eggs.otherfunction()
Even in this example, one could avoid updating globals() directly by using setattr(import_module(__name__), name, submodule), emphasizing that we are "setting an attribute" instead of "creating a variable".

A different example of creating a variable 'eggs' in the Python shell
>>> import sys
>>> module = sys.modules[__name__]
>>> module.eggs = 'Humpty Dumpty'
>>> eggs
'Humpty Dumpty'
Here is a function to pollute any global dictionary
>>> def pollute_caller_globals():
...     import sys
...     d = sys._getframe(1).f_globals
...     for name in "foobar foo bar baz qux quux corge grault garply waldo fred plugh".split():
...         d[name] = name[::-1].capitalize()
... 
>>> 
>>> pollute_caller_globals()
>>> 
>>> baz
'Zab'
>>> grault
'Tluarg'
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', 
'__spec__', 'bar', 'baz', 'corge', 'foo', 'foobar', 'fred', 
'garply', 'grault', 'plugh', 'pollute_caller_globals', 
'quux', 'qux', 'waldo']
As mention use data stucture eg a @dataclass() is a simple way.
from dataclasses import dataclass

@dataclass()
class Var:
    x: float
    y: float
    z: int = 1

var = Var(1.5, 2.5)
print(var)
Output:
Var(x=1.5, y=2.5, z=1)
So data is mutable and can change as wish.
If want it immutable just add @dataclass(frozen=True).
>>> var.x = 100.4
>>> var.x
100.4
>>> var
Var(x=100.4, y=2.5, z=1)
The data is also stored in dictionary,to see this can call like this.
>>> var.__dict__
{'x': 100.4, 'y': 2.5, 'z': 1}
Just to clarify this is this same as making variables like this.
>>> x = 100.4
>>> y = 2.5
>>> z = 1
Now will these variables go into globals dictionary,as Gribouillis show some examples of.
But should not mess with globals and use normal visible data structure as eg shown here.
If you unfamiliar with dataclass,here is the same as a ordinary class.
class Var:
    def __init__(self, x: float, y: float, z: int = 1):
        self.x = x
        self.y = y
        self.z = z

    def __repr__(self):
        return f"Var(x={self.x}, y={self.y}, z={self.z})"

var = Var(1.5, 2.5)
print(var)
Output:
Var(x=1.5, y=2.5, z=1)
Could you describe why you think you need to create variables? Defining variables is a coding operation. A variable is just a convenient name that is used to access an object. During coding, the programmer keeps track of the variable names. Who keeps track of variable names when they are generated automatically?
Thank you @Gribouillis @buran @snippsat @deanhystad for your input :)

Meanwhile I did create what I was needed with dictionary.

But thanks to yours reply, I will improve it and make a class based on -->

(Aug-09-2023, 03:25 PM)snippsat Wrote: [ -> ]
class Var:
    def __init__(self, x: float, y: float, z: int = 1):
        self.x = x
        self.y = y
        self.z = z

    def __repr__(self):
        return f"Var(x={self.x}, y={self.y}, z={self.z})"

var = Var(1.5, 2.5)
print(var)

Dance (the happy dance)