Python3中的單例模式 hasattr() getattr() serattr() delattr()


#python中單例模式
#1.使用__new__ class Singleton: def __new__(cls,*args,**kwargs): if not hasattr(cls,'_instance'): cls._instance=super().__new__(cls) return cls._instance s0=Singleton() s1=Singleton() print(id(s0)) print(id(s1)) 
In [10]:
#hasattr(object,name)函數用於判斷是否包含對應的屬性
#參數: object------對象 name------字符串,屬性名 #返回值: 如果對象有該屬性返回True,否則返回False class People: country="china" def __init__(self,name): self.name=name def people_info(self): print("%s is xxx"%(self.name)) obj=People('aaa') print(obj.name) print(hasattr(People,'country')) print(hasattr(obj,'name')) print(hasattr(People,'name')) print(hasattr(People,'people_info')) print(hasattr(obj,'people_info')) print(People.__dict__) print(obj.__dict__) 
 
aaa
True
True
False
True
True
{'__module__': '__main__', 'country': 'china', '__init__': <function People.__init__ at 0x0000024A642A7A60>, 'people_info': <function People.people_info at 0x0000024A642A78C8>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None}
{'name': 'aaa'}
In [14]:
#2.使用裝飾器
from functools import wraps def singlenton(cls): instances={} @wraps(cls) def getinstance(*args,**kwargs): if cls not in instances: instances[cls]=cls(*args,**kwargs) return instances return getinstance @singlenton class Bar: pass b0=Bar() b1=Bar() print(id(b0)) print(id(b1)) 
 
2518531933456
2518531933456
 

裝飾器的用法(小應用)

def outer(func): def inner(): print("before func") ret=func() return ret+1 return inner #返回inner函數

@outer #解釋器執行 foo=outer(foo) def foo(): return 1

print(foo) foo()

 

這個過程中執行了下面幾步

1.函數 foo 作為 裝飾器 outer 的參數被傳入 2.函數 inner 對 func 進行調用,然后裝飾器 outer 返回 inner 3.原來的函數名 foo 關聯到 inner,如上面的foo 所示,調用 foo時間上是在調用 inner

In [ ]:
#裝飾器的應用小例子
#將對象作為函數的參數,去判斷對象參數 def wrapper(func): def checker(a,b): if a.x<0 or a.y <0: a=Coordinate(a.x if a.x>0 else 0,a.y if a.y>0 else 0) if b.x<0 or b.y<0: b=Coordinate(b.x if b.x>0 else 0,b.y if b.y>0 else 0) ret=func(a,b) if ret.x<0 or ret.y<0: ret = Coordinate(ret.x if ret.x>0 else 0,re.y if ret.y>0 else 0) return ret return checker class Coordinate(object): def __init__(self,x,y): self.x=x self.y=y def __repr__(self): return "Coord:"+str(self.__dict__) @wrapper def add(a,b): return Coordinate(a.x+b.x,a.y+b.y) @wrapper def sub(a,b): return Coordinate(a.x-b.x,a.y-b.y) one=Coordinate(100,200) two=Coordinate(300,400) three=Coordinate(-100,-100) sub(one,three) add(one,three) sub(one,two) # print(one) 
In [ ]:
def hello(cls): cls.hello=staticmethod(lambda:"hello") return cls @hello class World(object): pass World.hello 
In [ ]:
#使用元類,可以控制類的創建過程
class Singleton(type): '''元類繼承type''' _instance={} def __call__(cls,*args,**kwargs): if cls not in cls._instance: cls._instance[cls]=super().__call__(*args,**kwargs) return cls._instance class Bar(metaclass=Singleton): pass b0=Bar() b1=Bar() print(id(b0)) print(id(b1)) ''' 輸出結果: 2473667780824 2473667780824 '''

#裝飾器還可以為類增加額外的成員

def hello(cls): cls.hello=staticmethod(lambda:"hello") return cls @hello class World(object): pass World.hello #<function __main__.hello.<locals>.<lambda>()> World.hello() 
Out[3]:
'hello'
In [6]:
#functools.wraps 則可以將原函數對象的指定屬性復制給包裝函數對象, 默認有 __module__、__name__、__doc__,或者通過參數選擇
from functools import wraps def logged(func): @wraps(func) def with_logging(*args,**kwargs): print(func.__name__+'was called') return func(*args,**kwargs) return with_logging @logged def f(x): '''does some math''' return x+x*x def f(x): '''does some math''' return x+x*x f=logged(f) f.__name__ #'f' f.__doc__ 
Out[6]:
'does some math'
In [15]:
def logged(func): def with_logging(*args,**kwargs): print(func.__name__+'was called') return func(*args,**kwargs) return with_logging @logged def f(x): '''does some math''' return x+x*x def f(x): '''does some math''' return x+x*x f=logged(f) f.__name__ #'with_logging' print(f.__doc__) 
 
None
In [ ]:
Python裝飾器decorator在實現的時候被裝飾后的函數其實已經是另外一個函數了函數名等函數屬性會發生改變), 為了不影響Python的functools包中提供了一個叫wraps的decorator來消除這樣的副作用寫一個decorator的時候最好在實現之前加上functools的wrap它能保留原有函數的名稱和docstring
In [17]:
#使用元類,可以控制類的創建過程
class Singleton(type): '''元類繼承type''' _instance={} def __call__(cls,*args,**kwargs): if cls not in cls._instance: cls._instance[cls]=super().__call__(*args,**kwargs) return cls._instance class Bar(metaclass=Singleton): pass b0=Bar() b1=Bar() print(id(b0)) print(id(b1)) 
 
2473667780824
2473667780824
In [ ]:
#getattr()函數
#用於返回一個對象的屬性值 #getattr(object,name,default) ''' 參數 : object-----對象 name------字符串,對象屬性 default ----默認返回值,如果不提供該參數,在沒有對象屬性時,將觸發AttributeError 返回值: 放回對象屬性值 ''' 
In [23]:
class People: country='chaina' def __init__(self,name): self.name=name def people_info(self): print('%s is xxx'%(self.name)) obj=getattr(People,'country') print(obj) ''' obj1=getattr(People,'countryjjjjj') print(obj1)#沒有屬性的話,又沒有默認屬性參數的話,就會報錯 ''' obj=getattr(People,'conutryjjjjj',None) print(obj) 
 
chaina
None
In [24]:
#setattr()函數
''' setattr函數,用於設置屬性值,該屬性必須存在 語法:setattr(object,name,value) 參數: object----對象 name------字符串,對象屬性 value-----屬性值 返回值: ''' class People: country='china' def __init__(self,name): self.name=name def people_info(self): print('%s is xxx'%(self.name)) obj=People('aaa') setattr(People,'x',111)#等同於People.x=111 print(People.x) print(obj.__dict__) print(People.__dict__) 
 
111
{'name': 'aaa'}
{'__module__': '__main__', 'country': 'china', '__init__': <function People.__init__ at 0x0000023FF21688C8>, 'people_info': <function People.people_info at 0x0000023FF21686A8>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None, 'x': 111}
In [25]:
#delattr()函數
''' delattr函數用於刪除屬性 delattr(x,'foobar')相當於del x.doobar 語法: setattr(object,name) 參數: object ---對象 name--必須是對象的屬性 返回值: ''' class People: country='China' def __init__(self,name): self.name=name def people_info(self): print('%s is xxx' %(self.name)) delattr(People,'country') #等同於del People.country print(People.__dict__) 
 
{'__module__': '__main__', '__init__': <function People.__init__ at 0x0000023FF2168D08>, 'people_info': <function People.people_info at 0x0000023FF2168AE8>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None}
In [ ]:
class Foo: def run(self): while True: cmd=input('cmd>>:'.strip()) if hasattr(self,cmd): func=getattr(self,cmd) func() def download(self): print('download.....') def upload(self): print('upload...') obj=Foo() obj.run() 
 
cmd>>:download
download.....
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM