https://docs.python.org/3.6/reference/datamodel.html#special-method-names
http://www.cnblogs.com/btchenguang/archive/2012/09/17/2689146.html
新式类都有一个__new__
的静态方法,它的原型是object.__new__(cls[, ...])
cls
是一个类对象,当调用C(*args, **kargs)
来创建一个类C的实例时,python的内部调用是 :
C.__new__(C, *args, **kargs)
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是所有新式类的基类。
如果__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)
{}
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>
print(someobj)会调用someobj.str(), 如果str没有定义,则会调用someobj.repr().
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)
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