Python面试要如何理解__new__和__init__的区别?

2022年11月12日11:05:27编程语言入门到精通评论66 views字数 1777阅读模式

Python中的__init__是构造方法,但其实不然,Python中真正的构造方法是__new__。__init__和__new__有什么区别?本文就来探讨一下。

我们先来看一下__init__的用法

class Person(object):
    def __init__(self, name, age):
        print("in __init__")
        self._name = name
        self._age = age 

p = Person("Wang", 33) 

上面的代码会输出如下的结果

in __init__
<__main__.Person object at 0x7fb2e0936450>

那么我们思考一个问题,Python中要实现Singleton怎么实现,要实现工厂模式怎么实现?

用__init__函数似乎没法做到呢~

实际上,__init__函数并不是真正意义上的构造函数,__init__方法做的事情是在对象创建好之后初始化变量。真正创建实例的是__new__方法。

我们来看下面的例子

class Person(object):
    def __new__(cls, *args, **kwargs):
        print("in __new__")
        instance = object.__new__(cls, *args, **kwargs)
        return instance

    def __init__(self, name, age):
        print("in __init__")
        self._name = name
        self._age = age

p = Person("Wang", 33)

上面的代码输出如下的结果

in __new__
in __init__

上面的代码中实例化了一个Person对象,可以看到__new__和__init__都被调用了。__new__方法用于创建对象并返回对象,当返回对象时会自动调用__init__方法进行初始化。__new__方法是静态方法,而__init__是实例方法。

好了,理解__new__和__init__的区别后,我们再来看一下前面提出的问题,用Python怎么实现Singleton,怎么实现工厂模式?

先来看Singleton

class Singleton(object):
    _instance = None
    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = object.__new__(cls, *args, **kwargs)

        return cls._instance

s1 = Singleton()
s2 = Singleton()
print(s1)
print(s2) 

上面的代码输出

<__main__.Singleton object at 0x7fdef58b1190>
<__main__.Singleton object at 0x7fdef58b1190>

可以看到s1和s2都指向同一个对象,实现了单例模式。

再来看下工厂模式的实现

class Fruit(object):
    def __init__(self):
        pass

    def print_color(self):
        pass

class Apple(Fruit):
    def __init__(self):
        pass

    def print_color(self):
        print("apple is in red")

class Orange(Fruit):
    def __init__(self):
        pass

    def print_color(self):
        print("orange is in orange")

class FruitFactory(object):
    fruits = {"apple": Apple, "orange": Orange}

    def __new__(cls, name):
        if name in cls.fruits.keys():
            return cls.fruits[name]()
        else:
            return Fruit()

fruit1 = FruitFactory("apple")
fruit2 = FruitFactory("orange")
fruit1.print_color()    
fruit2.print_color()    

上面的代码输出

apple is in red
orange is in orange

看完上面两个例子,大家是不是对__new__和__init__的区别有了更深入的理解?

  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/ymba/30123.html
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定