Python 内置的object对象(1)

来源:互联网 发布:免费oa办公系统源码 编辑:程序博客网 时间:2024/05/29 08:51

https://docs.python.org/3.6/reference/datamodel.html#special-method-names
http://www.cnblogs.com/btchenguang/archive/2012/09/17/2689146.html

__new__ and __init__

新式类都有一个__new__的静态方法,它的原型是object.__new__(cls[, ...])
cls是一个类对象,当调用C(*args, **kargs)来创建一个类C的实例时,python的内部调用是 :

  1. C.__new__(C, *args, **kargs)
  2. 然后返回值是类C的实例c
  3. 确认c是C的实例后
  4. python再调用C.__init__(c, *args, **kargs)来初始化实例c

所以调用一个实例c = C(2),实际执行的代码为:

c = C.__new__(C, 2)     if isinstance(c, C):         C.__init__(c, 23)#__init__第一个参数要为实例对象 

object.__new__()创建的是一个新的,没有经过初始化的实例。当重写__new__方法时,可以不用使用装饰符@staticmethod指明它是静态函数,解释器会自动判断这个方法为静态方法。如果需要重新绑定C.__new__方法时,只要在类外面执行C.__new__ = staticmethod(yourfunc)就可以了。

此外,如果(新式)类中没有重写__new__()方法,即在定义新式类时没有重新定义__new__()时,Python默认是调用该类的直接父类的__new__()方法来构造该类的实例,如果该类的父类也没有重写__new__(),那么将一直按此规矩追溯至object的__new__()方法,因为object是所有新式类的基类。

例1:

如果__new__()没有返回cls(即当前类)的实例,那么当前类的__init__()方法是不会被调用的。如果__new__()返回其他类(新式类或经典类均可)的实例,那么只会调用被返回的那个类的构造方法。

class C(object):    def __new__(cls,*args,**kwargs):        print(cls)        print(args)        print(kwargs)        #这里并没有返回一个instance,所以__init__不会被调用    def __init__(self,a,b):        print('__init__ called')        print('self is', self)        self.a=a        self.b=ba=C(1,2)

运行的结果是:

<class '__main__.C'>(1, 2){}

例2:

class C(object):    def __new__(cls,*args,**kwargs):        print(cls)        print(args)        print(kwargs)        new_instance = object.__new__(cls)        return new_instance         #返回一个instance,之后__init__被调用    def __init__(self,a,b):        print('__init__ called')        print('self is', self)        self.a=a        self.b=ba=C(1,2)

运行的结果是:

<class '__main__.C'>(1, 2){}__init__ calledself is <__main__.C object at 0x7fef84b0a438>

__repr__ and __str__

print(someobj)会调用someobj.str(), 如果str没有定义,则会调用someobj.repr().

例1:

http://stackoverflow.com/questions/1984162/purpose-of-pythons-repr

>>> class Point:...   def __init__(self, x, y):...     self.x, self.y = x, y...   def __repr__(self):...     return 'Point(x=%s, y=%s)' % (self.x, self.y)>>> p = Point(1, 2)>>> pPoint(x=1, y=2)

例2:

class C:    def __init__(self):        self.classattr = 'attr on class'    def __repr__(self):        print('call __repr__')        return self.classattr    def __str__(self):        print('call __str__')        return self.classattrcobj = C()cobj.instattr = "attr on instance"cobj# call __repr__# attr on classprint(cobj)# call __str__# attr on classrepr(cobj)# call __repr__# attr on class
0 0