python幾個面試題目:單例模式,淺拷貝與深拷貝
阿新 • • 發佈:2019-02-16
主要參考git上一篇面試題目,連結如下https://github.com/taizilongxu/interview_python#2-python%E4%B8%AD%E7%9A%84%E5%85%83%E7%B1%BBmetaclass
實現單例模式,對每種方式新增更詳細的分析。
每個物件的初始化會先呼叫__new__生成物件,再呼叫__init__完成後續的初始化,super(para1, cls)中的para1表示,在mro序列中從para1開始尋找下一個類,也就是繼承樹中的para1之前的第一個類,後邊的__new__為尋找到的類的函式,由於所有類都繼承自object,而object類的__new__函式被定義為static型別,故還要再傳入cls引數。class Singleton(object): _instance = None def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance = super(Singleton, cls).__new__(cls) cls._instance.__init__(*args, **kwargs) return cls._instance def __init__(self, *args, **kwargs): pass a = Singleton() b = Singleton() print(id(a)) print(id(b))
這個方式生成物件要呼叫類方法get_instance,不夠方便,可以使用裝飾器方法實現。class Singleton(object): __instance = None def __init__(self, *args, **kwargs): pass @classmethod def get_instance(cls, *args, **kwargs): if Singleton.__instance is None: Singleton.__instance = Singleton(*args, **kwargs) return Singleton.__instance a = Singleton.get_instance() b = Singleton.get_instance() print(id(a)) print(id(b))
import模組是天然的單例模式,在模組裡建好例項,每次使用從模組中引入例項。def singleton(cls): _instance = None def get_instance(*args, **kwargs): if not _instance: obj = cls(*args, **kwargs) return obj return get_instance @singleton #想達到的目的程式碼obj = MyClass(*args, **kwargs) #裝飾器作用MyClass = singleton(MyClass),將MyClass指向get_instance函式 #實際執行程式碼obj = get_instance(*args, **kwargs) class MyClass(object): pass a = MyClass() b = MyClass() print(id(a)) print(id(b))
#singelton.py
class Singeton(object):
def __init__(*args, **kwargs):
pass
def foo(self):
pass
singelton_obj = Singeton()
#to use
from singleton import singelton_obj
print(id(singelton_obj))
from singleton import singelton_obj
print(id(singelton_obj))
再整理下引用,copy與deepcopy的區別。
import copy
a = [1, 2, 3, 4, ['a', 'b']]
b = a#傳物件的引用
c = copy.copy(a)#物件拷貝,淺拷貝
d = copy.deepcopy(a)#物件拷貝,深拷貝
a.append(5)
a[4].append('c')
print(a)#[1, 2, 3, 4, ['a', 'b', 'c'], 5]
print(b)#[1, 2, 3, 4, ['a', 'b', 'c'], 5]
print(c)#[1, 2, 3, 4, ['a', 'b', 'c']]
print(d)#[1, 2, 3, 4, ['a', 'b']]
賦值只是改變引用,原來物件資料變化,b也跟著變化。淺拷貝後為兩個獨立物件,但子物件為引用,仍然指向原來的子物件,故改變子物件資料,c也會跟著改變。深拷貝將所有物件資料獨立,原物件的改變不會影響d。