Python 内置的object对象(1)

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=b

a=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=b

a=C(1,2)

运行的结果是:

<class '__main__.C'>
(1, 2)
{}
__init__ called
self 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)
>>> p
Point(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.classattr

cobj = C()
cobj.instattr = "attr on instance"

cobj
# call __repr__
# attr on class

print(cobj)
# call __str__
# attr on class

repr(cobj)
# call __repr__
# attr on class

你可能感兴趣的:(Python)