Reputation: 29
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.
Upvotes: 0
Views: 1268
Reputation: 6730
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)
Upvotes: 1