7-1 如何派生内置不可变类型(int,str,tuple,float)并修改实例化行为
解决方案:
定义类IntTuple继承内置tuple,并实现new,修改实例化行为
比如我们需要做一个定制化的浮点数,只取小数点后面2位
class MyFloat(float):
def __init__(self,floatDigit):
super(MyFloat,self).__init__(self,floatDigit)
def __new__(cls,floatDigit):
return super(MyFloat,cls).__new__(cls,round(floatDigit,2))
python在__init__调用之前其实对象已经生成好了,在__init__就是直接使用self对象
__new__在__init__之前被调用,__new__的返回值(实例)将传递给__init__方法的第一个参数,然后__init__给这个实例设置一些参数
允许继承不可变类型(str,int, tuple)
class super(object)
| super(type) -> unbound super object
| super(type, obj) -> bound super object; requires isinstance(obj, type)
| super(type, type2) -> bound super object; requires issubclass(type2, type)
| Typical use to call a cooperative superclass method:
| class C(B):
| def meth(self, arg):
| super(C, self).meth(arg)
|
| Methods defined here:
|
| __get__(...)
| descr.__get__(obj[, type]) -> value
|
| __getattribute__(...)
| x.__getattribute__('name') <==> x.name
|
| __init__(...)
| x.__init__(...) initializes x; see help(type(x)) for signature
|
| __repr__(...)
| x.__repr__() <==> repr(x)
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __self__
| the instance invoking super(); may be None
|
| __self_class__
| the type of the instance invoking super(); may be None
|
| __thisclass__
| the class invoking super()
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| __new__ = <built-in method __new__ of type object>
| T.__new__(S, ...) -> a new object with type S, a subtype of T
比如实现整型tuple
class IntTuple(tuple):
def __init__(self,iterable):
#before
print self #在 __new__中已经生成好了
super(IntTuple,self).__init__(iterable)
#after
def __new__(cls,iterable):
g=( x for x in iterable if isinstance(x,int) and x >0 )
return super(IntTuple,cls).__new__(cls,g)
t=IntTuple([1,-1,'abc',6,['x','y'],3])
print t
class MyFloat(float):
def __init__(self,floatDigit):
super(MyFloat,self).__init__(self,floatDigit)
def __new__(cls,floatDigit):
return super(MyFloat,cls).__new__(cls,round(floatDigit,2))
a=MyFloat(2.32533)
print a
print issubclass(MyFloat, MyFloat)