-3

I am relatively new to Python and am asking myself if it is possible to create classes where names are dynamically created within a function?

Code:

def create_dummy_elements():
    rows = [A,B,C,D,E,F,G,H,I]
    columns = [A,B,C,D,E,F,G,H,I]

    for r in range (rows):
        for c in range (columns):
            ***** = element(1,1,1,False)

My result should be 81 objects of the class "element" named like AA,AB,AC,AD, ... * is what I am actually asking for ...

5
  • Do you wanna create a python file with those classes in the file ? or you want to create different instances of that class? Commented Oct 24, 2013 at 21:49
  • 2
    It would be simpler to set up a dictionary of elements indexed by the names you want. Then once it's set up you could say for instance elems['AA'] to get the AA element. Commented Oct 24, 2013 at 21:50
  • 2
    Your example doesn't illustrate this part "create classes which names are dynamically created within a function" Commented Oct 24, 2013 at 21:53
  • stackoverflow.com/questions/2320945/… Commented Oct 24, 2013 at 21:53
  • what You are asking for " if it is possible to create classes which names are dynamically created within a function." can be done with type function but example is for different question Commented Oct 24, 2013 at 21:55

3 Answers 3

1

You can make a list of these objects, but it's not ideal to create variable names dynamically.

Something like this:

my_list_of_elements = []
for r in range (rows):
    for c in range (columns):
        my_list_of_elements.append(element(1,1,1,False))

Then you can access them by index number, for example: my_list_of_elements[n]

or to match the two-dimensional style for loops you have:

my_list_of_elements = []
for r in range (rows):
    temp = []
    for c in range (columns):
        temp.append(element(1,1,1,False))
    my_list_of_elements.append(temp)

then you can do my_list_of_elements[i][j] to access the i-th row and the j-th column.

If you prefer a string index, a dictionary would serve you well:

my_dict_of_elements = {}
for r in range (rows):
    for c in range (columns):
        my_dict_of_elements["element"+(r*c+c)] = element(1,1,1,False)

which will give you access like this my_dict_of_elements["element0"] for example.

As mentioned in the comment by atomicinf on this post, you can use the globals() dict, but it seems we both agree there are better practices.

Sign up to request clarification or add additional context in comments.

2 Comments

Well, you can create variable names dynamically (playing with the globals() dict), but there's really no reason to do that ever.
Oh forgot about that business, I'll fix my wording, but I don't think I would ever recommend that when you can just use a data structure.
1

I think you can just can create list as suggested farmerjoe, but if you really want to add namespases to global, you can do it like

class element(object):
    def __init__(self, *args):
        self._args = args
    def __repr__(self):
        return ' '.join(map(str, self._args))


rows = ['A','B']
columns = ['A','B']

for r in rows:
    for c in columns:
        exec('%s%s = element(r,c,False)' % (r,c))

print AB

output will be

A B False

3 Comments

Aswering this way I feel myself handling a hand grenade to a monkey :) What do community think about too mature answers for on newbee's questions?
Instead of exec, you could simply use globals()[r+c] = element(r, c, False). Or better yet, create a reference to globals (to avoid repeatedly calling it, such as _globals = globals()), then using _globals[r+c] = blah blah blah.
there is one caveat here, try globals()[4]=5 versus exec('4=5')
0

Although it's possible to create classes and named instance of classes dynamically in Python, doing so is generally frowned upon. It's considered more "Pythonic" and elegant to store collections of such things in a container of some sort such as a list or dictionary, and then access them when necessary by index or key. Here's how that might apply to your problem:

class Element(object):
    def __init__(self, name, a=None, b=None, c=None):
        self.name, self.a, self.b, self.c = name, a, b, c
    def __str__(self):
        classname = self.__class__.__name__
        return('{classname}('
               'name={self.name}, b={self.a}, '
               'c={self.b}, d={self.c})'.format(classname=classname,
                                                self=self))
board = {}  # empty dictionary
for row in 'ABCDEFGHI':
    for col in 'ABCDEFGHI':
        name = row+col
        board[name] = Element(name)  # assign a named Element instance

# sample usage
board['AB'].a = 42
print board['AB']  # Element(name=AB, a=42, b=None, c=None)
board['GD'].c = 'something'
print board['GD']  # Element(name=GD, a=None, b=None, c=something)

Note: I don't really know what to call most of the attributes of the Element class, so am just using a, b, and c in the above for illustration purposes.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.