Search code examples
pythonpython-3.xattributesgetattr

Trying to Print Values of Attributes... Code Needs Improvement


class User():

    def __init__(self, first, last, location, gender):
        self.first = first
        self.last = last
        self.location = location
        self.gender = gender
        self.loginattempt = 0

    def mmplusattempt(self):
        self.loginattempt += 1

    def mmresetattempt(self):
        self.loginattempt = 0


    def mmdescribe(self):
        attributes = [a for a in dir(self) if not a.startswith(('__', 'mm'))]
        for att in attributes:
            print(att + ": " + str(getattr(self, att))) 


new = User('david', 'johnson', 'usa', 'male')
new.mmdescribe()

output:

└─$ python3 classuser.py
first: david
gender: male
last: johnson
location: usa
loginattempt: 0

The problem is, or was that attributes = [a for a in dir(self) if not a.startswith('__')] was returning all the attributes including plusattempt resetattempt describe which I don't want. I did not want to print any of the methods so I thought maybe I can make all the method names start with mm and filter them out using a.startswith(('__', 'mm'))]. Now this definitely works, but I feel there has to be a better way that I can't think of right now. Also if there was an attribute (that is not a method) that I didn't want to print, I would have to add mm to the name, which is not very efficient.

  1. How would I be able to print the attributes of new excluding the methods? (Other than the way I showed) I'm sure there is a more elegant way to write this.

Solution

  • I would recommend using vars, and implementing __str__ rather than using your mmdescribe method:

    class User:
    
        def __init__(self, first, last, location, gender):
            self.first = first
            self.last = last
            self.location = location
            self.gender = gender
            self.loginattempt = 0
    
        def plusattempt(self):
            self.loginattempt += 1
    
        def resetattempt(self):
            self.loginattempt = 0
    
        def __str__(self):
            return "\n".join(f"{k}: {v}" for k, v in vars(self).items())
    
    user = User("david", "johnson", "usa", "male")
    print(user)
    

    Output:

    first: david
    last: johnson
    location: usa
    gender: male
    loginattempt: 0
    >>>