Reputation: 1625
So i want to something like this in Python:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return self.name, self.age
p = Person('A', 20)
Then hope to call object p directly to get the tuple (self.name, self.age)
But as you can see when you run this program, you get the problem:
TypeError: __repr__ returned non-string (type tuple)
How can have this behavior?
Thanks!
Note: The problem is not specific to the tuple data type; it can be anything, like a pandas dataframe for example. I just want to return some attribute data, whatever type it is.
Upvotes: 6
Views: 4078
Reputation: 55499
Another option is to make the class instance callable, and return the desired tuple when called. Eg,
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f'Person({self.name}, {self.age})'
def __call__(self):
return self.name, self.age
p = Person('A', 20)
print(p)
t = p()
print(t, type(t))
output
Person(A, 20)
('A', 20) <class 'tuple'>
Upvotes: 1
Reputation: 5333
Since __repr__
is supposed to return something, which looks like a valid Python expression, you may choose to implement __str__
instead (even if this implementation would fit both purposes):
def __str__(self):
return "Person({}, {})".format(self.name, self.age)
Update: If a tuple is actually desired, you simply have to use an non-predefined routine:
def get_attributes(self):
return self.name, self.age
Upvotes: 0
Reputation: 10007
As the error suggest, your __repr__
must return a string
def __repr__(self):
return self.name + str(self.age)
Now, if your goal is to write a custom way of representing your object as a tuple, what you are looking for is _iter__
instead,
def __iter__(self):
yield self.name
yield self.age
p = Person('A', 20)
print(tuple(p))
>>>>('A', 20)
Upvotes: 5
Reputation: 532268
You can make Person
iterable:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __iter__(self):
yield self.name
yield self.age
name, age = p
Upvotes: 1
Reputation: 1794
Adding on, maybe you're looking for a namedtuple
- it would give you exactly what you're looking for:
from collections import namedtuple
Person = namedtuple('Person', 'name, age')
So you'd basically get a tuple every time you created a person (you'd get unpacking and such)- however, the object person will be immutable, not sure if that's what you're shooting for here.
Upvotes: 0