【问题标题】:Trying to Print Values of Attributes... Code Needs Improvement尝试打印属性值...代码需要改进
【发布时间】:2021-07-20 03:20:05
【问题描述】:
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 的属性(不包括方法)? (除了我展示的方式)我相信还有一种更优雅的方式来写这个。

【问题讨论】:

  • 也许this 会有所帮助。

标签: python python-3.x attributes getattr


【解决方案1】:

我建议使用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
>>> 

【讨论】:

  • 没想到__str__,我觉得是这个解决办法
【解决方案2】:

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

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

如果您有大量描述性属性,您可以考虑将它们存储在有序容器中,以避免为每个属性编写打印语句。 (向构造函数参数添加验证留给读者练习。)

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

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

【讨论】:

  • you're trying to be too clever 永远不会太聪明哈哈,但每当我觉得我是,我就把问题带到这里,看看我是不是真的太聪明了还是有答案
猜你喜欢
  • 1970-01-01
  • 2016-02-05
  • 1970-01-01
  • 2016-03-20
  • 1970-01-01
  • 1970-01-01
  • 2015-06-27
  • 1970-01-01
  • 2012-12-17
相关资源
最近更新 更多