0

I am trying to figure out a way to get at the object which owns an attribute from the attribute itself. This example is basically what I am trying to do. Any ideas?

import random

class Data(object):
  def __init__(self, index):
     self.index = index
     self.val = random.random()

class Log(object):
  def __init__(self):
     self.timestamp = '09:50'
     self.data = []
     for i in range(0, 20, 5):
        self.data.append(Data(i))

def get_timestamp_from_data(data):
  pass

log = Log()
cur_data = log.data[2]

data_timestamp = get_timestamp_from_data(cur_data)
Ferguzz
  • 5,777
  • 7
  • 34
  • 41
  • There's no concept of object ownership in Python. Every reference is created equal. Why do you think you need this? –  Mar 11 '13 at 17:36
  • 1
    Your example doesn't seem to be related to your question. Does `get_timestamp_from_data` need access to `log`? Why can't you just pass `log` to it, or make it a closure? – Henry Keiter Mar 11 '13 at 17:36
  • Or you can 'collect' all your objects in the upper class. [Link][1] [1]: http://stackoverflow.com/a/9460070/2153744 – aronadaal Mar 11 '13 at 17:47

3 Answers3

2

It cannot be done.

In python objects don't really own other objects. So your data is not owned by the log. The object merely stores a reference to the list. Multiple objects could reference the list. The list itself doesn't keep track of who references it. So there is no way to get back to Log from the list.

Winston Ewert
  • 44,070
  • 10
  • 68
  • 83
0

There's no built-in way to do this, since objects may be referenced by any number of references. However, it's still easy enough to just give your child objects a reference to their parent.

class Data(object):
    def __init__(self, index, parent_obj=None):
        self.index = index
        self.parent_obj = parent_obj # Refer back to the log (or whatever!)
        self.val = random.random()

class Log(object):
    def __init__(self):
        self.timestamp = '09:50'
        self.data = [Data(i, self) for i in range(0, 20, 5)]

def get_timestamp_from_data(data):
    try:
        return data.parent_obj.timestamp
    except AttributeError:
        print 'data is not associated with a log'
        return None # Obviously error handling is up to you.

log = Log()
cur_data = log.data[2]
data_ts = get_timestamp_from_data(cur_data)
print data_ts # Prints 09:50
Henry Keiter
  • 16,863
  • 7
  • 51
  • 80
0

You will need some reference to the timestamp in the Data object itself. There is no implicit "ownership" between objects. They are only linked together because you explicitly do so (typically by giving one object a reference to another). Here are two methods:

First, by adding a reference to the Log object...

class Data(object):
    def __init__(self, log, index):
        self.log = log
        self.index = index
        self.val = random.random()

    @property
    def timestamp(self):
        return self.log.timestamp

class Log(object):
  def __init__(self):
     self.timestamp = '09:50'
     self.data = []
     for i in range(0, 20, 5):
        self.data.append(Data(self, i))

def get_timestamp_from_data(data):
    return data.timestamp 

...and another, which copies the timestamp to the Data object...

class Data(object):
    def __init__(self, index, timestamp):
        self.index = index
        self.timestamp = timestamp
        self.val = random.random()

class Log(object):
  def __init__(self):
     self.timestamp = '09:50'
     self.data = []
     for i in range(0, 20, 5):
        self.data.append(Data(self.timestamp, i))

def get_timestamp_from_data(data):
    return data.timestamp

Which you use (and I'm sure there are other methods) are up to you. Note that if for any reason the timestamp changes in Log, the first example will show that the timestamp changes in data, but in the second example, it will not...

log = Log()
cur_data = log.data[2]
print(log.timestamp) # Prints '09:50'
log.timestamp = '10:00'
print(log.timestamp) # Prints '10:00'
print(cur_data.timestamp)

This last line will print "10:00" if you use the first sample I've provided, since the data is retrieved from the reference from log. If you implement using the second way, you'll print "9:50", since the timestamp was "copied" from the log object when it was created. In this case, the Data object will contain a copy of its own timestamp.

Mark Hildreth
  • 42,023
  • 11
  • 120
  • 109