Reputation: 6651
As I understand it, there are no references in python to int
s or float
s or similar data. Nevertheless, I am working on a problem where it would be very convenient for me if I could do something like
a=1
b=2
c=3
ref_dict={'field1':ref_to_var_a,'field2':ref_to_var_b,'field3':ref_to_var_c}
and then
def update(field,value):
ref_dict[field]=value
And so if the user called
update('field2',5)
the value of b
would become 5.
Is there any way this can be done? Thanks.
In response to arbanert's helpful comment and answer, what I really want to do is -- surprise, surprise -- more complicated. I am building a GUI with wxPython. I have many TextCtrl controls, each of which will set the value of one variable. Of course, I could write one method for each control, or I could write a single method, which would look something like
def handleTextEvent(self,event):
if (event.GetEventObject() == widget1):
a=int(event.GetString)
elif (event.GetEventObject() == widget2):
b= ....
I think you can see why I don't like this either. It would be nice if I could just do one short function like:
def handleTextEvent(self,event):
ref_dict[event.GetEventObject()]=int(event.GetString())
And, yes, I am very new with wxPython.
Thanks!
Upvotes: 0
Views: 2561
Reputation: 365767
This is possible, but it's almost always a bad idea.
Assuming a
, b
, and c
are globals:
ref_dict = {'field1': 'a', 'field2': 'b', 'field3': 'c'}
def update(field, value):
globals()[ref_dict[field]] = value
If you really want to, you can even create "reference wrappers":
class GlobalReference(object):
def __init__(self, name):
self.name = name
def get(self):
return globals()[self.name]
def set(self, value):
globals()[self.name] = value
ref_dict = {'field1': GlobalReference('a'), 'field2': GlobalReference('b')}
def update(field, value):
ref_dict[field].set(value)
And if you want to wrap things that aren't in globals
, like globals from another module, class attributes, instance attributes, etc.? Create more reference wrapper types:
class NamespaceReference(object):
def __init__(self, namespace, name):
self.namespace, self.name = namespace, name
def get(self):
return getattr(self.namespace, self.name)
def set(self, value):
setattr(self.namespace, self.name, value)
ref_dict = {'field1': GlobalReference('a'), 'field2': NamespaceReference('myobj', 'b')}
Or you can forgo the classes and just store setter functions…
So, if this is a bad idea, what's the right answer?
Without knowing what you're trying to do, it's hard to say, but here are some possibilities:
dict
variable full of values instead of a bunch of separate variables.For your specific case, I think what you want is the second one. This is standard model-view-controller design. Or, if you don't like MVC, model-template-view or some other variant (you don't really need a controller here).
Your model is a bunch of scattered globals, which is why it's hard to hook it up to the view. The simplest answer is to represent the model as an object. Then give the view (or its controller) a reference to this model, which is trivial, and you're done.
Upvotes: 2