0

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.

foobar
  • 23
  • 5
  • 2
    This smells like [XY problem](https://en.wikipedia.org/wiki/XY_problem) – buran Feb 16 '23 at 19:06
  • 1
    Which _infinite self-referencing_? If you fix the obvious syntax errors, above should work fine. – tkausl Feb 16 '23 at 19:06
  • @buran, what is an XY problem? – shivankgtm Feb 16 '23 at 19:06
  • 2
    @shivankgtm See https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem – AKX Feb 16 '23 at 19:06
  • 1
    @shivankgtm it's when you want to solve problem X, and you think the solution is Y, so you ask for help with Y, without mentioning X, when really, what you actually needed to solve X was Z. But nobody knows about X so they cannot know to suggest Z. – Random Davis Feb 16 '23 at 19:13
  • 1
    Can you clarify what you mean by "does not work due to infinite self-referencing"? [It seems to work perfectly fine](https://tio.run/##dY/BCsMgEETvfsUelZag6a2QbxGTKrUEFfXSrzeuUjAtnYMws@ybNbzz07tbKduuUoL2ijuBqoc2IKV1NktJk94N6zkK7bSqCAvwc6hq1DFzXyJkQM9/0FcIKmqX/frSW/4uMt7/Fo0LdXqyqNorat5/RFl17eDLAoJzHE6qgTEgIVqX6Sdjox/BSGClHA) – Pranav Hosangadi Feb 16 '23 at 19:20
  • The infinite self-referencing comes from the fact that class1 and class2 are dictionaries: __dict__ of class1 contains the __dict__ of class2. If I save the __dict__ of class 1 in class2 I cant iterate over the dict due to infinite self-referencing. – foobar Feb 16 '23 at 19:30
  • Do both classes inherit `dict`? How do you iterate over the `__dict__`? @foobar – Pranav Hosangadi Feb 16 '23 at 19:50
  • They inherit from another class but implement all needed functions that I omitted in the example above. The error occurs in `__repr__` of class1 that iterates over `__dict__` to filter entries. – foobar Feb 16 '23 at 20:05

1 Answers1

2

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]
Random Davis
  • 6,662
  • 4
  • 14
  • 24