如何派生内置不可变类型并修改实例化行为。

个人理解,如何派生出自己想要的类。

 class IntTuple(tuple):

     def __new__(cls,iterable):
g = (x for x in iterable if isinstance(x, int) and x>0)
return super(IntTuple,cls).__new__(cls,g) def __init__(self,iterable):
super(IntTuple,self).__init__(iterable) t = IntTuple([1,-1,'abc',6,[7,'y'],3])
print t

类的创建是在__new__中实现的,所以要修改new。

关于使用__slots__,在创建class时,定义slots属性,声明实例属性列表,这就等于关闭掉__dict__属性,dict的作用是允许对class进行动态添加属性。使用slots可以节省内存,对封装有好处。

关于上下文管理,也就是在class中设置__enter__,__exit__属性,这样就可以配合with使用了。ps:with语句中,无论如何都会执行exit方法。

在设置__enter__属性时,要注意返回的对象是不是self,一般来说都是。

在设置__exit__属性时,要注意接收的参数, def __exit__(self,exc_type,exc_val,exc_tab),需要接收异常信息。

注意,如果在exit中设置了return Ture。则错误会被包在with中而不传回给最上层。

关于property的用法。

 class Circle(object):
def __init__(self,r):
self.r = r def getR(self):
return round(self.r,2)#四舍五入两位小数 def setR(self,value):
if not isinstance(value,(int,long,float)):
raise ValueError('wrong type.')
self.r = float(value) def getArea(self):
return round(self.r ** 2* pi) R = property(getR,setR)#将方法定义到属性 c =Circle(3.2)
print c.R
c.R = 5

为类添加比较的属性,如__lt__,__le__,__gt__,__ge__,__eq__,__ne__这些属性。(小于,小于等于,大于,大于等于,等于,不等于)

比较两个类的大小,如 r1<r2 实际上就是 r1.__lt__(r2)方法的调用。

但是如果要添加6个属性显得很麻烦,所以可以使用functools.total_ordering方法,将其作为装饰器,赋给class,然后只用定义__lt__,__eq__就可以实现6个属性的比较了。

 from functools import total_ordering
from abc import abstractmethod,ABCMeta @total_ordering
class Shape(object):
__metaclass__ = ABCMeta#定义这个类为抽象类,不可以被实例化
@abstractmethod#声明定义抽象方法,让各个子类去完善
def area(self):
pass def __lt__(self,obj):
if not isinstance(obj,Shape):
raise TypeError('obj is not shape.')
return self.area() <obj.area() def __eq__(self,obj):
if not isinstance(obj,Shape):
raise TypeError('obj is not shape.')
return self.area() == obj.area() class Rectangle(Shape):
def __init__(self,w,h):
self.w = w
self.h = h def area(self):
return self.w *self.h class Circle(Shape):
def __init__(self,r):
self.r = r def area(self):
return self.r ** 2 *3.14 r1 = Rectangle(3,5)
r2 = Rectangle(5,5)
c1 = Circle(5)
print r1 > r2
print c1 > r1

ps:要注意ABCMeta,abstractmethod的作用,理解抽象类以及抽象方法的定义。

深入了解类的构成,如 __get__,__set__,__del__ 这些方法的作用。

 #coding:utf8
class Attr(object):
def __init__(self,name,type_):
self.name = name
self.type_ = type_ def __get__(self,instance,cls):
return instance.__dict__[self.name] def __set__(self,instance,value):
if not isinstance(value,self.type_):
raise TypeError('expected an %s' % self.type_)
instance.__dict__[self.name] = value def __delete__(self,instance):
del instance.__dict__[self.name] class Person(object):
name = Attr('name',str)
age = Attr('age',int)
height = Attr('height',float) p = Person() p.age = ''
print p.age#这里就会报错

引入弱引用weakref的概念,弱引用可以创建一种能访问对象,但是不增加访问计数的对象。

ps:当对象被引用时,对象的引用计数+1,而当对象的引用计数为0时,对象将被回收。弱引用的好处是,在某种循环引用里,解决回收不及时的问题。

 #coding:utf8
import weakref class Data(object):
def __init__(self,value,owner):
self.owner = weakref.ref(owner)#如果不是弱引用,则删除实例也不会回收
self.value = value def __del__(self):#回收函数
print 'in Data.__del__' class Node(object):
def __init__(self,value):
self.data = Data(value,self) def __del__(self):
print 'in Node.__del__' node = Node(100)
del node

ps:注意,需要引用 弱引用的对象时,要用其方法,如:self.owner = weakref.ref(owner),调用self.owner时应为self.owner()

通过实例化 方法的名字 来调用

 class s1(object):
def A(self):
return 'A' class s2(object):
def B(self):
return 'B' class s3(object):
def C(self):
return 'C' def getS(s):
for name in ('A','B','C'):
f = getattr(s, name,None)#在这里寻找对应的方法,如果找不到就返回none
if f:
return f() a = s1()
b = s2()
c = s3()
t = [a,b,c]
print map(getS,t)

用operator.methodcaller也有类似功能。但是不太明白为什么要用这个。

最新文章

  1. 第七章 人工智能,7.6 DNN在搜索场景中的应用(作者:仁重)
  2. VisualSVN Server的配置和使用方法(转)
  3. 学习NSRulerView
  4. Highcharts使用简例 + 异步动态读取数据
  5. copy 和 strong(或retain)的区别
  6. 系统级I/O
  7. POJ3009 Curling
  8. android 自动化压力测试-monkey 3 命令参数
  9. dynamic_cast
  10. c++中string类的详解
  11. 常用linux命令和配置
  12. jQuery prop 全选和全不全
  13. Web 版 PowerDesigner (Canvas) 技术
  14. python2.6升级2.7
  15. ZFS建池建卷和格式化
  16. nexus 随笔
  17. 1.关于Java
  18. mysql 查询优化~sql优化通用
  19. SpringCloud报错: &quot;Field discoveryClient in com.controller.DcController required a bean of type &#39;com.netflix.discovery.DiscoveryClient&#39; that could not be found.&quot;
  20. 【读书笔记】iOS-关闭键盘的2种方法

热门文章

  1. 【codeforces】【比赛题解】#864 CF Round #436 (Div.2)
  2. js面试题之求数组最值
  3. git —— pycharm+git管理/编辑项目
  4. caffe细节
  5. ZOJ 3962 Seven Segment Display(数位DP)
  6. HBase集群的搭建
  7. Java学习笔记之:Spring MVC 环境搭建
  8. caffe for python
  9. CI框架的事务开启、提交和回滚
  10. 批量ssh登录,获取操作系统、CPU、内存、硬盘信息&lt;shell&gt;