带你声明 Python 中的动态属性

本文讲的是带你声明 Python 中的动态属性,


以下实例均为 Python 3.5 版本,但同样适用于 Python 2.x 和 Python 3.x 版本。

重写类中的 __getattr__ 魔术方法是 Python 中实现动态属性的很普通的方法。试想有这样一个数据词典 AttrDict,它允许类似属性的方式访问其存储的键值对:

class AttrDict(dict):
    def __getattr__(self, item):
        return self[item]

这个简化的 AttrDict 类允许以类似属性的方式获取数据字典的值,同时,它允许一种非常简单的方式来设置键值对的值。无论哪种情况下,它都可以这样做:

>>> attrd = AttrDict()
... attrd["key"] = "value"
... print(attrd.key)
value

重写 __getattr__ 方法(和 __setattr__ 方法)非常有用——这能够让你的构建远程过程调用(RPCs)单元的代码更具可读性。然而,动态属性也有令人沮丧的地方——它们在使用之前是不可见的!

动态属性在交互的 shell 下有两大使用问题。第一个问题就是当用户使用 dir 方法去检查对象的 API 的时候,它们并不会出现:

>>> dir(attrd)  # 我想知道如何使用 attrd
['__class__', '__contains__', ... 'keys', 'values']
>>> # 没有动态属性 [傲娇脸]

第二个问题是自动完成——如果我们照常设置 normal_attribute 属性,大部分主流的 shell 环境 1 下都能自动完成。

但是以字典键值对的方式设置 dynamic_attribute 的时候并没有自动完成功能:

然而,你可以在实现动态属性的时候锦上添花地实现 __dir__ 方法,这样不但能提高用户体验还能一石二鸟地解决以上两个问题。详见 文章

如果对象内有名为 __dir__()的方法,方法被调用时必须返回属性列表。这使得对象可以实现一个自定义的__getattr__() 或者 __getattribute__() 方法,来自定义 dir() 方法输出属性的方式。

实现 __dir__ 方法非常简单,只需返回对象的属性键名列表:

class AttrDict(dict):
    def __getattr__(self, item):
        return self[item]

    def __dir__(self):
        return super().__dir__() + [str(k) for k in self.keys()]

这样 dir(attrd) 将会返回动态属性和普通属性。有趣的是,shell 环境将会使用 __dir__ 方法来进行自动完成提示!因此我们毫不费力就实现了自动完成 2功能:






原文发布时间为:2016年11月22日


本文来自合作伙伴掘金,了解相关信息可以关注掘金网站。

时间: 2025-01-31 06:05:50

带你声明 Python 中的动态属性的相关文章

Python中的几种数据类型

  大体上把Python中的数据类型分为如下几类: Number(数字) 包括int,long,float,complex String(字符串) 例如:hello,"hello",hello List(列表) 例如:[1,2,3],[1,2,3,[1,2,3],4] Dictionary(字典) 例如:{1:"nihao",2:"hello"} Tuple(元组) 例如:(1,2,3,abc) Bool(布尔) 包括True.False 由于P

Python中的装饰器用法详解

来源:http://www.jb51.net/article/59867.htm 来源:http://blog.csdn.net/mdl13412/article/details/22608283 这篇文章主要介绍了Python中的装饰器用法,以实例形式详细的分析了Python中的装饰器的使用技巧及相关注意事项,具有一定参考借鉴价值,需要的朋友可以参考下 本文实例讲述了Python中的装饰器用法.分享给大家供大家参考.具体分析如下: 这里还是先由stackoverflow上面的一个问题引起吧,如

举例介绍Python中的25个隐藏特性_python

注:这里忽略了生成器,装饰器,交换变量等熟知技巧1. 函数参数unpack 老生常谈的了:   def foo(x, y): print x, y alist = [1, 2] adict = {'x': 1, 'y': 2} foo(*alist) # 1, 2 foo(**adict) # 1, 2 2. 链式比较操作符  >>> x = 3 >>> 1 < x < 5 True >>> 4 > x >=3 True 3.

Python中使用中文的方法_python

先来看看python的版本: >>> import sys >>> sys.version '2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit (Intel)]' (一) 用记事本创建一个文件ChineseTest.py,默认ANSI: s = "中文" print s 测试一下瞧瞧: E:\Project\Python\Test>python ChineseTest.py

利用Python中的mock库对Python代码进行模拟测试_python

 如何不靠耐心测试 通常,我们编写的软件会直接与那些我们称之为"肮脏的"服务交互.通俗地说,服务对我们的应用来说是至关重要的,它们之间的交互是我们设计好的,但这会带来我们不希望的副作用--就是那些在我们自己测试的时候不希望的功能. 比如,可能我们正在写一个社交软件并且想测试一下"发布到Facebook的功能",但是我们不希望每次运行测试集的时候都发布到Facebook上. Python的unittest库中有一个子包叫unittest.mock--或者你把它声明成一

《Python游戏编程入门》——1.3 Python中的对象

1.3 Python中的对象 Python是面向对象编程语言,这意味着,它至少支持一些面向对象编程概念.现在,我们将花一些时间来介绍这些概念,因为这是一种编写代码的高效方式.面向对象编程(OOP)是一种方法学,也就是做事情的方式.在计算机科学中,有几种较大的."伞状的"方法学,也就是说,定义了编程语言的功能的方法学.要让我们的技能成为可以传播的,方法学对于这个产业来说很重要.如果每个公司使用他们自己的方法学,那么,为该公司工作的过程中所获取的技能,对于另一个不同的组织来说将会是无用的.

Python中列表的一些基本操作知识汇总

  这篇文章主要介绍了Python中列表的一些基本操作知识汇总,皆属于Python的基本功,需要的朋友可以参考下 Python最基本的数据结构是序列(列表/元组).一个序列中的每个元素都分配有一个数字- 它的位置或索引.第一个索引是0,第二个索引是1,依此类推. Python有6内置类型的序列,但最常见的是列表和元组,我们将在本教程中看到. 有一些东西可以使用所有序列类型来做.这些操作包括索引,切片,加,乘,并检查成员.此外,Python已经内置函数查找序列的长度和搜索它的最大和最小的元素. P

Python中Django框架下的staticfiles使用简介

  这篇文章主要介绍了Python中Django框架下的staticfiles使用简介,staticfiles是一个帮助Django管理静态资源的工具,需要的朋友可以参考下 django1.3新加入了一个静态资源管理的app,django.contrib.staticfiles.在以往的django版本中,静态资源的管理一向都是个问题.部分app发布的时候会带上静态资源文件,在部署的时候你必须手动从各个app中将这些静态资源文件复制到同一个static目录.在引入staticfiles后,你只需

探究Python中的正则表达式

  这篇文章主要介绍了Python中的正则表达式的一些用法,正则表达式的使用是Python学习进阶中的重要知识,需要的朋友可以参考下 字符串是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在.比如判断一个字符串是否是合法的Email地址,虽然可以编程提取@前后的子串,再分别判断是否是单词和域名,但这样做不但麻烦,而且代码难以复用. 正则表达式是一种用来匹配字符串的强有力的武器.它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它"匹配&q