Skip to content

Commit bf12f36

Browse files
committed
add translated for 'Python: Declaring Dynamic Attributes'
1 parent 4ea8520 commit bf12f36

File tree

3 files changed

+66
-67
lines changed

3 files changed

+66
-67
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
原文:[Python: Declaring Dynamic Attributes](http://amir.rachum.com/blog/2016/10/05/python-dynamic-attributes/)
2+
3+
---
4+
5+
下面的例子用的是Python 3.5,但除此之外,这篇文章同时也适用于Python 2.x和3.x
6+
7+
在Python中覆盖类中的`__getattr__`魔术方法,以实现动态属性,这是一种常见的解决方法。想想`AttrDict`,它是一个字典,允许如属性般访问它存储的键值对:
8+
9+
```python
10+
class AttrDict(dict):
11+
def __getattr__(self, item):
12+
return self[item]
13+
```
14+
15+
简化的`AttrDict`允许像属性一样从它读取字典值,但是也允许_设置_键值对是非常简单的。无论如何,下面是对它的操作:
16+
17+
```python
18+
>>> attrd = AttrDict()
19+
... attrd["key"] = "value"
20+
... print(attrd.key)
21+
value
22+
```
23+
24+
覆盖`__getattr__` (和`__setattr__`)是非常有用的,从简单的诸如`AttrDict`这样让你的代码更具可读性的“噱头”,到你的应用中诸如远程过程调用(RPC)这样的基本组成部分。然而,动态属性有些让人郁闷的地方 —— 在你用之前,无法看到它们!
25+
26+
当工作在一个交互式shell中的时候,东太熟悉有两个可用性问题。第一个是,当用户通过调用`dir`方法来试图检查对象的API时,它们并不出现:
27+
28+
```python
29+
>>> dir(attrd) # I wonder how I can use attrd
30+
['__class__', '__contains__', ... 'keys', 'values']
31+
>>> # No dynamic attribute :(
32+
```
33+
34+
第二个问题是自动完成 —— 如果我们用老方法将`normal_attribute`设置成一个熟悉,那么在大部分的现代shell环境下,可以自动完成(下面是来自IDLE的shell截图):
35+
36+
![](/images/posts/normal_attribute.png)
37+
38+
但是通过将`dynamic_attribute`当成一个键值对插入来设置它的时候,并不会自动完成:
39+
40+
![](/images/posts/dynamic_attribute_before.png)
41+
42+
然而,在实现动态属性的时候,你可以采取一个额外的方法,该方法将会让你的用户感到愉悦,并且[一石二鸟](https://www.youtube.com/watch?v=71gilEP4aJY) - **实现`__dir__`方法**。来自[文档](https://docs.python.org/2/library/functions.html#dir)
43+
44+
> 如果对象有一个名为`__dir__()`的方法,那么这个方法将会被调用,并且必须返回属性列表。这允许实现了自定义的`__getattr__()`或者`__getattribute__()`函数的对象自定义`dir()`报告属性的方式。
45+
46+
实现`__dir__`是很简单的:返回该对象的属性名列表:
47+
48+
```python
49+
class AttrDict(dict):
50+
def __getattr__(self, item):
51+
return self[item]
52+
53+
def __dir__(self):
54+
return super().__dir__() + [str(k) for k in self.keys()]
55+
```
56+
57+
这会让`dir(attrd)`返回动态属性,以及常规属性。关于这个的一个有趣的事情是,**shell环境通常使用`__dir__`来提供自动完成选项建议!**因此,无需任何额外的努力,我们就得到了自动完成:
58+
59+
![](/images/posts/dynamic_attribute_after.png)
60+
61+
[Hacker News](https://news.ycombinator.com/item?id=12644164), [/r/Programming](https://www.reddit.com/r/programming/comments/55zuip/python_declaring_dynamic_attributes/), 或者下面的评论部分**讨论**这篇文章。
62+
63+
**感谢**[Ram Rachum](http://ram.rachum.com)阅读了本文草稿。

Python Common/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,6 @@
6666

6767
- [不可不知的一点Python陷阱](./不可不知的一点Python陷阱.md)
6868

69-
在这篇文章中,它主要针对Python新手,会看到少量安全相关的小技巧;有经验的开发者可能会注意到后面的特殊性。
69+
在这篇文章中,它主要针对Python新手,会看到少量安全相关的小技巧;有经验的开发者可能会注意到后面的特殊性。
70+
71+
- [Python:声明动态属性](./Python:声明动态属性.md)

raw/Python:Declaring Dynamic Attributes.md

Lines changed: 0 additions & 66 deletions
This file was deleted.

0 commit comments

Comments
 (0)