您的位置:首页 > 编程语言 > Python开发

python 7-1 如何派生内置不可变类型(int,str,tuple,float)并修改实例化行为,继承内置tuple并实现__new__

2017-01-28 11:45 671 查看
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'],<
afdd
span class="hljs-number">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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: