pythonself-referenceinfinite-recursion

Given an adress, how can I access the object in Python?


How can I access a Python object by it's address that I get from id(self.__dict__)?

The background is the following, I want to access one class instance from the other (both classes mimic custom dictionaries):

class1:
    def __init__(self):
        self.a =  class2(self)
        # I also tried self.a = class2(self.__dict__) which also does not seem to be a good idea

class2:
    def __init__(self, parentobject):
        self.parentobject = parentobject     

As both class implement dictionaries, I can't iterate over them due to infinite self-referencing

One way to get it working, I thought, would to pass and save only the address of the "parent" class instance. But in order to access it, I would need to transform somehow the address into something I can access.

Edit: Some people are suggesting that it sounds like a XY problem. To me, a bit too. Therefore, the original problem: I want to implement a nested dictionary. The 'outer' dictionary contains only dictionaries of specific different types. These inner dictionaries hold some values, so:

dictionary["parameter1"]

gives something like {"bla": 42, "blubb":15} but this custom dictionary also allows for executing functions like

dictionary["parameter1"].evaluate()

This function depends on another parameter parameter2. So to access paramter2, I need somehow the other dictionary that holds parameter2 or I need a reference to the outer dictionary. So, what I tried to do above was to pass self of the outer dictionary to the inner dictionary. To hide this data, I reimplemented __repr__ where I iterate over __dict__ in order to skip the hidden keys. This is where the error is happening. So, I would be happy to find another better solution, but the most obvious one to me was to pass the address instead of the object.


Solution

  • This is a way to do what you're asking, but I'm not sure this works on just any implementation of Python besides the standard CPython, which uses the memory address of objects as their id. That's an implementation detail entirely specific to CPython though. As for whether you should even be trying to do this, I'm not here to judge that:

    import ctypes
    
    # create an object
    a = [1, 2, 3]
    
    # get the id of the object
    b = id(a)
    
    # access the object by its id
    c = ctypes.cast(b, ctypes.py_object).value
    
    # print the object
    print(c)  # output: [1, 2, 3]