Access to instance variable, but not instance method in Python

↘锁芯ラ 提交于 2019-12-25 01:00:51

问题


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?


回答1:


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.)




回答2:


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.




回答3:


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:

  1. 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():`

  2. 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.




回答4:


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.




回答5:


What does it mean or x?

self.names doesn't exists in scope, use instance_names.names instead.



来源:https://stackoverflow.com/questions/12171729/access-to-instance-variable-but-not-instance-method-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!