-3

I'm trying to refactor some code where I instantiate a lot of different classes and set their properties and wondered if I might be able to use a dictionary in some way.

Is it possible in python to get from the following:

class Class1:
    pass

class Class2:
    pass

class Class3:
    pass


test_dict = {"test1":Class1(), "test2":Class2(), "test3": Class3()}

to a list of class instances with the keys as the variable name. If the answer is no, that's fine.

Eg. I want

test1 = Class1()
test2 = Class2()
test3 = Class3()
5
  • The thing marked "I want" is not a list - what is it exactly that you are trying to do? Commented Apr 25 at 12:49
  • You want to create separate local (or global?) variables with their names being the keys of a dictionary, and their values being the corresponding values of each key? Commented Apr 25 at 12:50
  • 1
    I'm guessing "a list of" is to be interpreted as "a sequence of" not a list object in python. So maybe something like iterating the dictionary and using exec(), eval() or globals()[key] ? Commented Apr 25 at 12:51
  • Yes, list was a poor choice of word. I wanted separate local variables with variable names being the keys of the dictionary representing instances of the corresponding class. I think the answer using namespace achieves what I'm looking for Commented Apr 25 at 13:01
  • What’s the use-case of this? Commented Apr 26 at 15:53

3 Answers 3

3

You can use the locals() or globals() methods to access the dictionary of local and global variables respectively. So you can do this:

test_dict = {"test1":Class1(), "test2":Class2(), "test3": Class3()}
locals().update(test_dict)
print(test1)  # will print the representation of a Class1() instance
Sign up to request clarification or add additional context in comments.

6 Comments

What on Earth? Why would you start messing with locals() and globals() for something like this? Doesn't that give you a signal that this is not the right path?
What would you do roganjosh?
@roganjosh I gave an answer that directly addresses the OP's question, but if what the OP is asking is a bad idea, it would be better if you answered and explained why, and what would be a better alternative way.
@k314159 for starters, locals().update won't work in general (e.g. in in local scopes). But yeah, dynamically creating variables is generally a bad design choice. Just use the container
@Daviid I wouldn't do it. Refactoring code that seems cumbersome in one way into something that is a general anti-pattern in another way (looking at locals() and globals()) should not be viewed as an improvement. Something else is fundamentally wrong
|
0

It works similarly to how you described it. For instance:

class Classy:
    def __init__(self, val):
        print('Hello!')
        self.value = val
    def get_val(self):
        return self.value

test_dict = {"test1": Classy}

classy_obj = test_dict["test1"](3)
print(f'The value is {classy_obj.get_val()}')

This will instantiate an object of Classy, taken from test_dict, and print "Hello!"

The final line will print "The value is 3", as that's the argument that was passed the line before

Edit:

You can also initialise it in the dictionary's value with very minor changes

class Classy:
    def __init__(self, val):
        print('Hello!')
        self.value = val
    def get_val(self):
        return self.value

test_dict = {"test1": Classy(3)}

classy_obj = test_dict["test1"]
print(f'The value is {classy_obj.get_val()}')

Comments

-1
from types import SimpleNamespace

class Class1:
    def __init__(self):
        self.name = "Class1"
    def speak(self):
        return f"I am {self.name}"

class Class2:
    def __init__(self):
        self.name = "Class2"
    def speak(self):
        return f"I am {self.name}"

class Class3:
    def __init__(self):
        self.name = "Class3"
    def speak(self):
        return f"I am {self.name}"

# Dictionary of class instances
instance_dict = {
    "test1": Class1(),
    "test2": Class2(),
    "test3": Class3()
}

# Convert to a namespace (dot-access)
ns = SimpleNamespace(**instance_dict)

# Usage
print(ns.test1.speak())  # ➜ I am Class1
print(ns.test2.speak())  # ➜ I am Class2
print(ns.test3.speak())  # ➜ I am Class3

1 Comment

How does a namespace help here?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.