0

How can i access a class instance with it's name stored as a string.

For Example: i have a class: Feets and two instances of Feets: RF and LF

within both instances i need a value of the the other instance. Each Instance knows the name of the other one (f.e. LF.opposite = "RF") which is committed as argument on the creation of the instance (f.e. LF = Feets(x,x,x,"RF") As far as i know yet the getattr(object, name) do not accept a string as object.

I thank you in advance for your help!

user2488
  • 113
  • 2
  • Why don't you pass the instance instead of the variable name? `LF = Feets(x,x,x,RF)` – falsetru Aug 02 '15 at 10:07
  • Both instances are created separately. LF = Feets(x,x,x,RF) RF = Feets(x,x,x,LF) i guess i cannot pass RF to LF while RF is not already created! – user2488 Aug 02 '15 at 10:08
  • 1
    How about set `opposite` attribute for the first object later? `LF = Feets(x,x,x,None); RF = Feets(x,x,x,LF); LF.opposite = RF` – falsetru Aug 02 '15 at 10:10
  • that sounds like a plan. I'll try it. Thanks a lot! But i'm sure there must be a better way than handing over the whole object! – user2488 Aug 02 '15 at 10:13
  • You're not handing the object anywhere, you're referring to it. And it's way better than messing with variable names like that. – Lev Levitsky Aug 02 '15 at 10:15
  • Its not clear here what you are looking for - are you looking to access the existing class object by the attribute name? Why don't you pass in the class itself instead of a string representation of the class? – Burhan Khalid Aug 02 '15 at 10:15
  • possible duplicate of [Does python have an equivalent to Java Class.forName()?](http://stackoverflow.com/questions/452969/does-python-have-an-equivalent-to-java-class-forname) – rfkortekaas Aug 02 '15 at 10:18

2 Answers2

-1

You can probably do this with something hacky like

RF = locals()[LF.opposite]

However, it's better practice to just have the two instances hold references to each other than trying to reverse-engineer the other instance later, which is much more error prone. You can do this by deferring the setting of the opposite attribute until after both objects have been created

class Feets(object):
    def __init__(self):
        self.opposite = None

    def set_opposite(self, other):
        self.opposite = other
        other.opposite = self

LF = Feets()
RF = Feets()
LF.set_opposite(RF)
lemonhead
  • 5,328
  • 1
  • 13
  • 25
-1

You could of course do a lookup for the object in whatever scope it is. If the object is in global scope you find it by using globals()[name] if it's in a instance or class attribute you'd use getattr(obj_or_class, name).

However you could use an object that refers or can create the other object on demand instead of having to do a lookup - this would have the advantage of not needing to know where to lookup the other object. For example:

class FootCreator:
     def __init__(*args, **kwds):
          self.args = args
          self.kwds = kwds

     def other(self, other):
          self.other = other

     def __call__(self):
          try:
              return self.feets
          except:
               pass
          self.feets = Feets(other=self.other, *self.args, self.**kwds)
          return self.feets

class Feets:
     def get_other(self):
          return self.other()

The solution where you set the reference to the other explicitely after creation might be non-OO since it might break invariance (but on the other hand the objects will not be complete until the other has been created anyways). A similar solution would be to create and initialize the object separately:

lf = Feets.__new__() # lf created, but not initialized yet
rf = Feets.__new__() # rf created, but not initialized yet
lf.__init__(..., other=rf) # initialize (existing) lf
rf.__init__(..., other=lf) # initialize (existing) rf
skyking
  • 13,817
  • 1
  • 35
  • 57
  • Instead of just downvoting it would be useful to actually point out what is wrong with the answers. There now exists two answers which have been downvoted without any comment about what's wrong with them. – skyking Aug 02 '15 at 11:17