python 类中__new__ 和 __init__方法区别

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
    原文作者:黄哥
    原文地址: https://zhuanlan.zhihu.com/p/21379984
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞