1

Thanks for reading. Preface, I don't mean how to make a print(objectA) make python output something other than the <__main__.A object at 0x00000273BC36A5C0> via the redefining the __str__ attribute.

I will use the following example to try to explain what I'm doing.

class Point: ''' Represents a point in 2D space attributes: x, y ''' def __init__(self, x=0, y=0): allowed_types = {int, float} if type(x) not in allowed_types or type(y) not in allowed_types: raise TypeError('Coordinates must be numbers.') else: self.x = x self.y = y def __str__(self): return f' "the points name" has the points: ({self.x}, {self.y})' __repr__ = __str__ 

I would like the "the points name" to be replaced with whatever the variable name assigned to a specific object. So if I instantiated pointA=Point(1,0), I would like to be able to print pointA has the points: (1,0)

I can't seem to find anything like this online, just people having issues that are solved by redefining __str__. I tried to solve this issue by adding a .name attribute, but that made this very unwieldy (especially since I want to make other object classes that inherit Point()). I'm not entirely sure if this is possible from what I know about variable and object names in python, but after wrestling with it for a couple of days I'd figured I'd reach out for ideas.

4
  • 1
    You could do A=B=Point(), and have a point with multiple names. You could do print(Point()), and have a point that was never assigned to a name at all. This is simply not something that's going to work in Python. Commented Apr 8, 2022 at 2:02
  • Most cases where programmers feel they need to tell the users the name of a variable in their code, are cases where they should be using a dictionary instead. Users should never need to know the names of variables in your code, as they can't (or shouldn't) interact with your code directly. Commented Apr 8, 2022 at 2:02
  • Are you looking for all references, or can this be limited to say, the global variables of a single module? In the latter case, you could enumerate names/objects and just check which of those objects are the one you want. Commented Apr 8, 2022 at 2:04
  • @Grismar I'm aware that this is not best practices, this is just a hobby for me and I'm more than willing to implement an unnecessaryand difficult method for an idea I had just to prove to myself that it could be done. Commented Apr 8, 2022 at 14:33

1 Answer 1

1

Note that an object may be referred to as multiple names. It is also possible that there is no object name referring to the object.

Below is one approach that achieves your goal. It uses globals(), the dictionary that stores mappings from names to objects inside the global environment. Essentially, the __str__ method searches the object in the global listings (so it can be very slow if there are many objects) and keeps the name if matches. You could possibly use locals instead to narrow the search scope.

In the example, C is referring to the same object as A. So print(C) tells both A and C are the names.

class Point: def __init__(self, x=0, y=0): self.x = x self.y = y def __str__(self): results = [] for name, obj in globals().items(): if obj == self: results.append(f' "{name}" has the points: ({self.x}, {self.y})') return "; ".join(results) A = Point() B = Point() print(A) #"A" has the points: (0, 0) print(B) # "B" has the points: (0, 0) C = A print(C) # "A" has the points: (0, 0); "C" has the points: (0, 0) 
Sign up to request clarification or add additional context in comments.

1 Comment

You might want to search local scopes too, because it could well be defined inside a class.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.