设为首页 收藏本站
查看: 1449|回复: 0

[经验分享] Python类中实例属性的通用显示工具

[复制链接]

尚未签到

发表于 2018-8-15 10:07:55 | 显示全部楼层 |阅读模式
  0.说明
  以下的思想方法非常有用,可以帮助你在Python开发提高开发和维护效率,所以可能的话,请仔细琢磨一下其中的代码。
  之前在用Python编写一个类时,为了显示的友好性,总是需要在每个类中重载__str__或者__repr__方法,现在有了更好的方法,不需要在每个类中都这么做了,下面给出的方法非常实用。
  下面使用的例子使用的Python版本都是Python3.5,但实际上在Python2.7中进行也没有任何影响。
  1.正常情况下类实例的不友好显示
  在Python中编写一个类时,由于没有重载__str__方法或者__repr__方法,所以在交互模式下输出一个类所创建的实例时,得到的往往是一些不太友好的显示,例如,考虑下面的一个类:
>>> class Person:  
...   def __init__(self, name, school, major):
  
...     self.name = name
  
...     self.school = school
  
...     self.major = major
  现在使用该类创建一个实例:
p = Person('xpleaf', 'GDUT', 'Network Engineer')  使用print()函数或者直接在交互模式下输出实例p:
>>> print(p)        # 如果使用Python2.7,则为print p  
<__main__.Person object at 0x7fcf69723d30>
  
>>>
  
>>> p
  
<__main__.Person object at 0x7fcf69723d30>
  可以看到,上面的输出中得不到我们想要的信息,即从输出中我们很难看出实例p的基本信息。
  2.使类实例在输出中友好显示的传统方法
  为了有更友好的输出显示,我们一般把上面的类重构为下面这种类型:
>>> class Person:  
...   def __init__(self, name, school, major):
  
...     self.name = name
  
...     self.school = school
  
...     self.major = major
  
...   def __str__(self):
  
...     return '[Person: %s, %s, %s]' % (self.name, self.school, self.major)
  
...   def __repr__(self):
  
...     return '[Person: %s, %s, %s]' % (self.name, self.school, self.major)
  即重载了__str__方法和__repr__方法,这时再重新创建一个实例:
>>> p = Person('xpleaf', 'GDUT', 'Network Engineer')  使用print()函数或者直接在交互模式下输出实例p:
>>> print(p)  
[Person: xpleaf, GDUT, Network Engineer]
  
>>>
  
>>> p
  
[Person: xpleaf, GDUT, Network Engineer]
  可以看到此时的输出是友好的,从输出的结果中我们可以很容易得知实例p的信息,需要说明的是,当使用print()函数时,输出的是__str__()方法返回的字符串,而直接在交互模式下输入p时,返回的是__repr__()方法返回的字符串。
  其实在很多时候,上面这样做已经可以达到友好显示实例的效果了,但是考虑一下,如果我们需要写大量的类,同时希望它们的实例的输出结果是友好,难道需要在每个类中都写类似重复的代码吗?实际上这样做是可以的,但是下面有更好的解决方法。
  3.编写一个通用工具来友好显示实例
  编写下面一个类,保存在classtools文件中:
class AttrDisplay:  
  def gatherAttrs(self):
  
    attrs = []
  
    for key in sorted(self.__dict__):
  
      attrs.append('%s=%s' % (key, getattr(self, key)))
  
    return ', '.join(attrs)
  
  def __str__(self):
  
    return '[%s: %s]' % (self.__class__.__name__, self.gatherAttrs())
  
  def __repr__(self):
  
    return '[%s: %s]' % (self.__class__.__name__, self.gatherAttrs())
  重构Person类,使其继承AttrDisplay类:
>>> from classtools import AttrDisplay  
>>>
  
>>> class Person(AttrDisplay):
  
...   def __init__(self, name, school, major):
  
...      self.name = name
  
...      self.school = school
  
...      self.major = major
  
...
  创建一个实例:
>>> p = Person('xpleaf', 'GDUT', 'Network Engineer')  使用print()函数或者直接在交互模式下输出实例p:
>>> print(p)  
[Person: major=Network Engineer, name=xpleaf, school=GDUT]
  
>>>
  
>>> p
  
[Person: major=Network Engineer, name=xpleaf, school=GDUT]
  可以看到达到了同样的效果,但是我们并没有在Person类中重载前面两个方法,这样的工作我们把它交给了AttrDisplay类来完成。
  事实上,只要我们编写的类继承了AttrDisplay属性,就可以友好的显示所创建的实例,这在需要创建大量类并且要求每个类的实例都要有友好输出时显示尤为有用。
  4.在实际场景中的使用
  在去年开发的Blog_mini(http://github.com/xpleaf/Blog_mini)中,由于需要定义各种类,同时因为需要在交互模式下对类进行测试,所以类中必须重载__str__方法或者__repr__方法,以使它们的输出可以更加清晰明确,但是由于当时并没有意识到这样的一种通用方法或者思想,所以每编写一个类都需要加入重复的代码,这不仅仅增加了代码量,对于维护也带来很大的不便。
  所以如果可以使用这里的方法,不仅可以精简代码量,同时也便于以后进行维护,所以在今年对Blog_mini的代码进行重构时,会考虑使用这样的思想方法。
  当然,如果实际中写的类不多,使用传统的方法就可以了,而且如果完全不需要在交互模式下进行类似的测试,也可以不用重载__str__和__repr__方法。
  5.参考资料
  《Python学习手册》 第四版 P670 “使用内省工具” 一小节

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-552062-1-1.html 上篇帖子: Linux Python详细安装、升级指南 下篇帖子: linux下编译安装python2.7.6
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表