__new__函數
在實例化開始之后,在調用 __init__() 方法之前,Python 首先調用 __new__() 方法
#單例1 class Singleton1(object): _inst=None # 在實例化開始之后,在調用 __init__() 方法之前,Python 首先調用 __new__() 方法 def __new__(cls,*args, **kwargs): if cls._inst is None: # 如果要得到當前類的實例,應當在當前類中的 __new__() 方法語句中調用當前類的父類的 __new__() 方法 cls._inst = super(Singleton1, cls).__new__(cls) #相當於object.__new__(cls) return cls._inst #單例2 class Singleton2(object): def __new__(cls,*args, **kwargs): if not hasattr(cls,'_inst'): cls._inst = object.__new__(cls) return cls._inst if __name__ == '__main__': print(Singleton1()) print(Singleton1()) print(Singleton2()) print(Singleton2())
class Person(object): def __init__(self, name, age): self.name = name self.age = age def __new__(cls, name, age): if 0 < age < 150: return super(Person, cls).__new__(cls) #return object.__new__(cls) else: return None def __str__(self): return '{0}({1})'.format(self.__class__.__name__, self.__dict__) print(Person('Tom', 10)) print(Person('Mike', 200))
@staticmethod、@classmethod修飾符
我們知道對於一個普通的類,我們要使用其中的函數的話,需要對類進行實例化,而一個類中,某個函數前面加上了staticmethod或者classmethod的話,那么這個函數就可以不通過實例化直接調用
@staticmethod不需要表示自身對象的self和自身類的cls參數,就跟使用函數一樣。
如果在@staticmethod中要調用到這個類的一些屬性方法,只能直接類名.屬性名或類名.方法名。
@classmethod也不需要self參數,但第一個參數需要是表示自身類的cls參數。
而@classmethod因為持有cls參數,可以來調用類的屬性,類的方法,實例化對象等,避免硬編碼。
class Animal(object): name = 'dog' def __init__(self,name): self.name = name def intro1(self): print('there is a %s'%(self.name)) @staticmethod def intro2(): print('there is a %s') @classmethod def intro3(cls): print('there is a %s'%(cls.name)) Animal('cat').intro1() Animal.intro2() Animal.intro3()
@property修飾符
property使方法像屬性一樣調用,就像是一種特殊的屬性
有參函數時,@name.setter
class Animal(object): def __init__(self,name): self.name = name @property def intro(self): print('there is a %s eating'%(self.name)) @intro.setter def intro(self,value): print('there is %d %s eating'%(value,self.name)) a = Animal('cat') a.intro a.intro=2
@修飾符
從第一個函數修飾符開始,自下而上做參數傳遞
#無參修飾 ,無參數時不需要調用 def log1(func): func() @log1 def test(): print('test:') #有參修飾 def log2(func): def inner(*args, **kwargs): func(*args, **kwargs) return inner @log2 def test(num): print('testlog2:',num,test.__name__) test(20) #相當於log(test(20)) from functools import wraps #可以看見@wraps可以保證裝飾器修飾的函數的name的值保持不變 #不參數的裝飾器 def log3(func): @wraps(func) def inner(*args, **kwargs,): func(*args, **kwargs) return inner @log3 def test(num): print('testlog3:',num,test.__name__) test(30) #相當於log(test(30))
@pysnooper修飾符
日志打印工具,用顯示函數間的入參和返回值的變化
import pysnooper @pysnooper.snoop() #@pysnooper.snoop('log.log') def lisy(a): b=[x - 10 if x in [11, 12, 13] else x for x in a] return b print(lisy([1,2,3,11,12,13,'111',222]))

