尝试打印属性值...代码需要改进

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()

输出:

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

问题是,或者是 attributes = [a for a in dir(self) if not a.startswith('__')] 返回了所有我不想要的属性,包括 plusattempt resetattempt describe。我不想打印任何方法,所以我想也许我可以让所有方法名称都以 mm 开头,然后使用 a.startswith(('__', 'mm'))] 过滤掉它们。现在这肯定行得通,但我觉得必须有一个我现在想不到的更好的方法。此外,如果有一个我不想打印的属性(不是方法),我将不得不在名称中添加 mm,这不是很有效。

  1. 如何打印 new 的属性(不包括方法)? (除了我展示的方式)我相信有更优雅的方式来写这个。

我建议使用 vars,并实施 __str__ 而不是使用您的 mmdescribe 方法:

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)

输出:

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

IMO 你太聪明了,简单的选择更容易理解并且工作得很好:

    def describe(self):
        print(f'first: {self.first}')
        print(f'last: {self.last}')
        print(f'location: {self.location}')
        print(f'gender: {self.gender}')

如果您有一组非常大的描述性属性,您可以考虑将它们存储在一个有序的容器中,以避免为每个 属性 写出打印语句。 (向构造函数参数添加验证留作 reader 的练习。)

class User():
    def __init__(self, **kwargs):
        # use an OrderedDict to maintain order when calling `describe`
        from collections import OrderedDict
        self.descriptors = OrderedDict((key, val) for key, val in kwargs.items())
        self.loginattempt = 0

    def describe(self):
        for key, val in self.descriptors.items():
            print(f'{key}: {val}')

>>> u = User(first='david', last='johnson', location='usa', gender='male')
>>> u.describe()
first: david
last: johnson
location: usa
gender: male

请记住,归根结底,难​​以编写的代码现在很不方便,但难以阅读的代码将永远是一场噩梦。