# temp

首先来看看上述三个魔法方法的定义吧：

（1）\_\_getattr\_\_(self, item):

在访问对象的item属性的时候，如果对象并没有这个相应的属性，方法，那么将会调用这个方法来处理。。。这里要注意的时，假如一个对象叫fjs,  他有一个属性：fjs.name = "fjs"，那么在访问fjs.name的时候因为当前对象有这个属性，那么将不会调用\_\_getattr\_\_()方法，而是直接返回了拥有的name属性了

（2）\_\_setattr\_\_(self, item, value):

当试图对象的item特性赋值的时候将会被调用。。

（3）\_\_getattribute\_\_(self, item):

这个只有在新式类中才有的，对于对象的所有特性的访问，都将会调用这个方法来处理。。。可以理解为在\_\_getattr\_\_之前

嗯。。。有了这几个方法就可以干很多很多的事情了。。。例如拦截器啥的。。。动态代理啥的。。。很方便就能实现了。。。起码比用java实现类似的功能方便多啦。。。。

不过需要注意的时候，在重写这些方法的时候需要特别的小心，因为容易引起循环调用。。。。

这里先来举一个例子，用于实现拦截所有的特性访问，在访问的时候打log啥的：**\[python]** [view plain](https://blog.csdn.net/fjslovejhl/article/details/40683547) [copy](https://blog.csdn.net/fjslovejhl/article/details/40683547)

1. \# -\*- coding: utf-8 -\*- &#x20;
2. class Fjs(object): &#x20;
3. &#x20;   def \_\_init\_\_(self, name): &#x20;
4. &#x20;       self.name = name &#x20;
5.
6. &#x20;   def hello(self): &#x20;
7. &#x20;       print "said by : ", self.name &#x20;
8.
9. &#x20;   def \_\_getattribute\_\_(self, item): &#x20;
10. &#x20;       print "访问了特性：" + item &#x20;
11. &#x20;       return object.\_\_getattribute\_\_(self, item) &#x20;
12.
13.
14. fjs = Fjs("fjs") &#x20;
15. print fjs.name &#x20;
16. fjs.hello() &#x20;

上述代码的输出如下：**\[python]** [view plain](https://blog.csdn.net/fjslovejhl/article/details/40683547) [copy](https://blog.csdn.net/fjslovejhl/article/details/40683547)

1. 访问了特性：name &#x20;
2. fjs &#x20;
3. 访问了特性：hello &#x20;
4. said by :  访问了特性：name &#x20;
5. fjs &#x20;

很简单就实现了拦截的功能吧。。。而且这里可以知道\_\_getattribute\_\_方法拦截了属性和方法的访问。。这里也就是所谓的所有的特性的访问了。。不过要注意的是：\_\_getattribute\_\_只有在新式类中才能用的。。。

嗯。。接下来配合使用\_\_getattr\_\_和\_\_getattribute\_\_来实现一个非切入式的编程：**\[python]** [view plain](https://blog.csdn.net/fjslovejhl/article/details/40683547) [copy](https://blog.csdn.net/fjslovejhl/article/details/40683547)

1. \# -\*- coding: utf-8 -\*- &#x20;
2. class Fjs(object): &#x20;
3. &#x20;   def \_\_init\_\_(self, name): &#x20;
4. &#x20;       self.name = name &#x20;
5.
6. &#x20;   def hello(self): &#x20;
7. &#x20;       print "said by : ", self.name &#x20;
8.
9. &#x20;   def fjs(self, name): &#x20;
10. &#x20;       if name == self.name: &#x20;
11. &#x20;           print "yes" &#x20;
12. &#x20;       else: &#x20;
13. &#x20;           print "no" &#x20;
14.
15. class Wrap\_Fjs(object): &#x20;
16. &#x20;   def \_\_init\_\_(self, fjs): &#x20;
17. &#x20;       self.\_fjs = fjs &#x20;
18.
19. &#x20;   def \_\_getattr\_\_(self, item): &#x20;
20. &#x20;       if item == "hello": &#x20;
21. &#x20;           print "调用hello方法了" &#x20;
22. &#x20;       elif item == "fjs": &#x20;
23. &#x20;           print "调用fjs方法了" &#x20;
24. &#x20;       return getattr(self.\_fjs, item) &#x20;
25.
26. fjs = Wrap\_Fjs(Fjs("fjs")) &#x20;
27. fjs.hello() &#x20;
28. fjs.fjs("fjs") &#x20;

这里通过\_\_getattr\_\_方法，将所有的特性的访问都路由给了内部的fjs对象。。。。。。

最后，关于\_\_setattr\_\_()方法，这个就不细说了。。。不过他的使用还需要特别注意一些。。因为稍不注意就容易陷入循环调用了。。。。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://jablack-programs.gitbook.io/python-notes/basic-syntax/temp.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
