Reputation: 9549
I'm a newbie to python and I think similar question have been asked (including this one: Can you use a string to instantiate a class in python?), but I don't understand the answers or how to apply them.
I'm trying to create multiple instances of a class using what i'll call 'instance names' in a list.
Here's an example of what I'm trying to do:
class InstanceNames():
def __init__(self):
self.names = ['inst1', 'inst2', 'inst3']
class DoSomething():
instances = []
def __init__(self):
DoSomething.instances.append(self)
instance_names = InstanceNames()
for x in range(len(instance_names.names)):
print x
# following line not working at creating instances of DoSomething
instance_names.names[x] = DoSomething()
print DoSomething.instances
I changed the list for loop, and now I'm getting the following output:
0
1
2
[<__main__.DoSomething instance at 0x10cedc3f8>, <__main__.DoSomething instance at 0x10cedc440>, <__main__.DoSomething instance at 0x10cedc488>]
did it work? I'm so confused i'm not sure.
Ok. This is some ugly code, but here's what I have now:
class InstanceNames():
def __init__(self):
self.i_names = {'inst1': None, 'inst2': None, 'inst3': None}
self.o_names = ['foo', 'bar', 'baz']
class DoSomething():
instances = []
def __init__(self, blah_blah):
DoSomething.instances.append(self)
self.name = blah_blah
def testy(self, a):
a = a * 2
instance_names = InstanceNames()
for x in range(len(instance_names.i_names)):
print x
instance_names.i_names[x] = DoSomething(instance_names.o_names[x])
print "\n"
print DoSomething.instances
print "\n"
for y in DoSomething.instances:
print y.name
print y.testy(4)
print "\n"
Here is my output:
0
1
2
[<__main__.DoSomething instance at 0x10dc6c560>, <__main__.DoSomething instance at 0x10dc6c5a8>, <__main__.DoSomething instance at 0x10dc6c5f0>]
foo
None
bar
None
baz
None
Why is the 'name' variable printing, but the 'testy' method is not?
Upvotes: 1
Views: 524
Reputation: 160073
You can use type
to create classes dynamically:
type_names = ["Class1", "Class2", "Class3"]
storage = {}
for t in type_names:
storage[t] = type(t, (object, ), {"your": "instance", "attributes": "here"})
for type_name in storage:
print type_name, "=>", storage[type_name]
Alternately, you can used collections.namedtuple
to generate lightweight classes if all you really need is a bunch of attributes.
What you currently have is creating three instances of the DoSomething
class and replacing the string values (which you don't use) in the InstanceNames
class' names
attribute with these three instances of DoSomething
.
Upvotes: 1
Reputation: 8942
instance_names.names
is a list which requires numbers as indices. In fact, the TypeError you posted says the same thing.
However, you want to set an element using a string in instance_names.names[x]
- where x
is a string. Lists don't allow this, you need to use a dictionary for that.
There are several ways to solve your problem:
You can use a dictionary for instance_names.names in the first place. Then, however, you must use a reserved object such as None
as a placeholder for instances that haven't been created yet: ´self.names = {'inst1': None, 'inst2': None, 'inst3': None}, and you must iterate through the keys of the dictionary:
for x in instance_names.names.keys():`
You can use a separate dictionary for the instances and set its content in the loop: self.instances = {}
. instance_names.instances[x] = ...
For further reading about Python's data types, I reccomend Dive Into Python.
Upvotes: 1
Reputation: 92647
Not that I have any idea what you are really trying to do, to address your specific code, a list is only a collection of values. What you are treating it like is a dict, which is an association between a key and value.
To make your example work, you would use a dict:
class InstanceNames():
def __init__(self):
self.names = {'inst1': None, 'inst2': None, 'inst3': None}
This will now allow the following expression to succeed:
instance_names.names[x] = DoSomething()
... Because names
is now a dict and you are accessing a key and assigning it a value.
Again, I make the disclaimer that I have no idea what this code is trying to do...have the feeling it is probably not good... but not taking the angle of judging it.
Upvotes: 1
Reputation: 251578
You seem to be asking "how do I take the string 'inst1' and make a variable called 'inst1'".
The answer is that you don't want to do that. Instead, create a dictionary or list mapping your strings to the objects in question. See this question for some examples.
(If that's not what you're asking please clarify your question.)
Upvotes: 1
Reputation: 6232
What does it mean or x
?
self.names
doesn't exists in scope, use instance_names.names
instead.
Upvotes: 0