python中有二个特殊的方法__new__ 和 __init__ 方法。听黄哥来讲解。
__init__ 方法为初始化方法, __new__方法才是真正的构造函数。
1、__new__方法默认返回实例对象供__init__方法、实例方法使用。
请看下面的代码。
# coding:utf-8
class Foo(object):
'''黄哥python培训,黄哥所写'''
price = 50
def how_much_of_book(self, n):
print(self)
return self.price * n
foo = Foo()
print(foo.how_much_of_book(8))
print(dir(Foo))
分析上面的代码,这个类实例化过程,Foo类继承object类,继承了object的__new__方法。
当你没有重载这个方法(通俗来说,你没有在Foo类中没有写__new__方法),Foo实例化是默认自动调用父类__new__方法,这个方法返回值为类的实例(self),提供这个函数how_much_of_book,默认的第一个参数self。
# coding:utf-8
class Foo(object):
price = 50
def __new__(cls, *agrs, **kwds):
inst = object.__new__(cls, *agrs, **kwds)
print(inst)
return inst
def how_much_of_book(self, n):
print(self)
return self.price * n
foo = Foo()
print(foo.how_much_of_book(8))
# <__main__.Foo object at 0x1006f2750>
# <__main__.Foo object at 0x1006f2750>
# 400
请看上面代码,Foo类中重载了__new__方法,它的返回值为Foo类的实例对象。
2、__init__ 方法为初始化方法,为类的实例提供一些属性或完成一些动作。
# coding:utf-8
class Foo(object):
def __new__(cls, *agrs, **kwds):
inst = object.__new__(cls, *agrs, **kwds)
print(inst)
return inst
def __init__(self, price=50):
self.price = price
def how_much_of_book(self, n):
print(self)
return self.price * n
foo = Foo()
print(foo.how_much_of_book(8))
# <__main__.Foo object at 0x1006f2750>
# <__main__.Foo object at 0x1006f2750>
# 400
3、__new__ 方法创建实例对象供__init__ 方法使用,__init__方法定制实例对象。
__new__ 方法必须返回值,__init__方法不需要返回值。(如果返回非None值就报错)
4、一般用不上__new__方法,__new__方法可以用在下面二种情况。
__new__() is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation. It is also commonly overridden in custom metaclasses in order to customize class creation.
继承不可变数据类型时需要用到__new__方法(like int, str, or tuple) 。
# coding:utf-8
class Inch(float):
"Convert from inch to meter"
def __new__(cls, arg=0.0):
return float.__new__(cls, arg*0.0254)
print(Inch(12))
用在元类,定制创建类对象。
# coding:utf-8
'''来自http://eli.thegreenplace.net/2011/08/14/python-metaclasses-by-example'''
class MetaClass(type):
def __new__(meta, name, bases, dct):
print '-----------------------------------'
print "Allocating memory for class", name
print meta
print bases
print dct
return super(MetaClass, meta).__new__(meta, name, bases, dct)
def __init__(cls, name, bases, dct):
print '-----------------------------------'
print "Initializing class", name
print cls
print bases
print dct
super(MetaClass, cls).__init__(name, bases, dct)
class Myclass(object):
__metaclass__ = MetaClass
def foo(self, param):
print param
p = Myclass()
p.foo("hello")
# -----------------------------------
# Allocating memory for class Myclass
# <class '__main__.MetaClass'>
# (<type 'object'>,)
# {'__module__': '__main__', 'foo': <function foo at 0x1007f6500>, '__metaclass__': <class '__main__.MetaClass'>}
# -----------------------------------
# Initializing class Myclass
# <class '__main__.Myclass'>
# (<type 'object'>,)
# {'__module__': '__main__', 'foo': <function foo at 0x1007f6500>, '__metaclass__': <class '__main__.MetaClass'>}
# hello