0
class Person:
def __init__(self, name, surname, age):
    self.name = name
    self.surname = surname
    self.age = age

def show(self):
    print(("Name: {}\nSurname: {}\nAge: {}").format(self.name, self.surname, self.age))

Is there more pythonic way to show these variables by function show?

I don't want spaghetti code when i have 34 variables in class

Drenek
  • 23
  • 4

3 Answers3

0

Not sure if it is more Pythonic or not, but instead of defining show you can override __repr__ (you will need to return that string instead of printing it). Then instead of calling person_obj.show you can simply do print(person_obj).

class Person:
    def __init__(self, name, surname, age):
        self.name = name
        self.surname = surname
        self.age = age

    def __repr__(self):
        return "Name: {}\nSurname: {}\nAge: {}").format(self.name,     self.surname, self.age)

print(Person('a','b', 'c'))
>> Name: a
   Surname: b
   Age: c

This will display correctly even if you have a list of persons:

print([Person('a', 'b', 'c'), Person('d', 'e', 'f')])
>> [Name: a
    Surname: b
    Age: c, Name: d
    Surname: e
    Age: f]
DeepSpace
  • 78,697
  • 11
  • 109
  • 154
  • It's not `__repr__` its `__str__`, `__repr__` is used for technical information, while `__str__` - to show data to user, so in this case, he should override `__str__` – wasd Nov 20 '16 at 13:45
  • @wasd If you override `str` then the objects still show as `` when they are part of a collection. This may or may not be what OP wants/needs. – DeepSpace Nov 20 '16 at 13:49
  • Well, it was not specified for what actual purposes it is done and I'd might agreed with you if his method was called debug not show, but for representation purposes it is still better and more pythonic to use `__str__` not `__repr__` – wasd Nov 20 '16 at 14:18
  • Btw, update your code, you haven't defined neither `__repr__` nor `__str__` – wasd Nov 20 '16 at 14:30
0

In the case you don't want to override __str__ and badly need show to print, not return data, it's still more pythonic to use format. I'd make few adjustment for your code:

def show(self):
    person_info = "Name {name}\nSurname {surname}\nAge {age}".format(name=self.name, surname=self.surname, age=self.age)
    print (person_info)

In general it's the same you had, just a bit more explicit.

wasd
  • 1,532
  • 3
  • 28
  • 40
0

You can take advantage of the classes' internal __dict__ property to avoid typing all of the variables twice. Additionally, it's best to use the __repr__ function for representing your class:

class Person(object):
    def __init__(self, name, surname, age):
        self.name = name
        self.surname = surname
        self.age = age

    def __repr__(self):
        return '\n'.join([
            'Name: {name}',
            'Surname: {surname}',
            'Age: {age}'
        ]).format(**self.__dict__)


john = Person('John', 'Doe', 42)
print(john)

Another step of abstraction you could take to avoid hardcoding the format string is to create a list of the properties that identify the instance and use them as follows:

class Person(object):
    _identifiers = ('name', 'surname', 'age')

    def __init__(self, name, surname, age):
        self.name = name
        self.surname = surname
        self.age = age

    def __repr__(self):
        return '\n'.join(
            '{k}: {v}'.format(k=key.capitalize(), v=self.__dict__[key])
            for key in self._identifiers
        )


john = Person('John', 'Doe', 42)
print(john)
Noah
  • 1,329
  • 11
  • 21