很多同學都以為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__的區別有了更深入的理解?
歡迎關注微信公眾號【Python與資料分析】
複製程式碼