Python--27 魔法方法 属性访问

属性访问

>>> class C:
...     def __init__(self):
...             self.x = 'X-man'
... 
>>> c = C()
>>> c.x
'X-man'
>>> getattr(c,'x','没有这个属性')
'X-man'
>>> getattr(c,'y','没有这个属性')
'没有这个属性'
>>> class C:
...     def __init__(self,size = 10):
...             self.size = size
...     def getSize(self):
...             return self.size
...     def setSize(self,value):
...             self.size = value
...     def delSize(self):
...             del self.size
...     x = property(getSize,setSize,delSize)
... 
>>> c = C()
>>> c.x
10
>>> c.x = 1
>>> c.x
1
>>> c.size
1
>>> del c.x
>>> c.size
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'C' object has no attribute 'size'

属性访问的魔法方法

 __getattr__(self, name)

  定义当用户试图获取一个不存在的属性时的行为

 __getattribute__(self, name)

  定义当该类的属性被访问时的行为

 __setattr__(self, name, value)

  定义当一个属性被设置时的行为

 __delattr__(self, name)

  定义当一个属性被删除时的行为
 

>>> class C:
...     def __getattribute__(self,name):
...         print('getattribute')
...         return super().__getattribute__(name);
...     def __getattr__(self, name):
...         print('getattr')
...     def __setattr__(self,name,value):
...         print('setattr')
...         super().__setattr__(name,value)
...     def __delattr__(self,name):
...         print('delattr')
...         super().__delattr__(name)
... 
>>> c = C()
>>> c.x
getattribute
getattr
>>> c.x =1
setattr
>>> del c.x
delattr

练习要求

  写一个矩形类,默认有宽和高两个属性

  如果为一个叫square的属性赋值,那么说明这是一个正方形,值就是正方形的边长,此时宽和高都应该等于边长。  

>>> class Rectangle:
...     def __init__(self, width = 0, height = 0):
...             self.width = width
...             self.height = height
...     def __setattr__(self, name, value):
...             if name == 'square':
...                     self.width = value 
...                     self.height = value
...             else:
...                     self.name = value
...     def getArea(self):
...             return self.width * self.height
... 
>>> r = Rectangle()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
  File "<stdin>", line 10, in __setattr__
  File "<stdin>", line 10, in __setattr__
  File "<stdin>", line 10, in __setattr__
  [Previous line repeated 327 more times]
RecursionError: maximum recursion depth exceeded

两种方法

  方法一:调用基类的__setattr__

  方法二:__dice__[name]

>>> r = Rectangle()
>>> r = Rectangle(4,5)
>>> r.getArea()
20
>>> r1.squre = 10
>>> r.square = 10
>>> r.getArea()
100
>>> r.__dict__
{'width': 10, 'height': 10, 'squre': 10}
>>> class Rectangle:
...     def __init__(self, width = 0, height = 0):
...         self.width = width        
...         self.height = height
...     def __setattr__(self, name, value):
...         if name == 'square':
...             self.width = value 
...             self.height = value
...         else:
...             self.__dict__[name] = value
...     def getArea(self):
...          return self.width * self.height
... 
>>> r = Rectangle()
>>> r = Rectangle(4,5)
>>> r.getArea()
20

 

posted @ 2017-09-13 15:56  110528844  阅读(191)  评论(0编辑  收藏  举报