property :
class Goods(object): def __init__(self): # 原价 self.original_price = 100 # 折扣 self.discount = 0.8 @property def price(self): new_price = self.original_price * self.discount return new_price @price.setter def price(self, value): self.original_price = value @price.deleter def price(self): del self.original_price obj = Goods() print(obj.price) obj.price = 200 print(obj.price) del obj.price
类成员修饰符:
class C: __name = "私有静态字段" def func(self): print(C.__name) # 类内部可以访问 class D(C): def show(self): print(C.__name) # 派生类中不可以访问 print(C.__name) # 类不可以访问 obj = C()
obj.func() obj_son = D() obj_son.show()
如果想要强制访问私有字段,可以通过 【对象._类名__私有字段明 】访问(如:obj._C__foo),不建议强制访问私有成员。
class C: def __init__(self): self.__foo = "私有字段" def func(self): print self.foo # 类内部访问 class D(C): def show(self): print self.foo # 派生类中访问 obj = C() obj.__foo # 通过对象访问 ==> 错误 obj.func() # 类内部访问 ==> 正确 obj_son = D(); obj_son.show() # 派生类中访问 ==> 错误
属性 :
#Python中的属性其实是普通方法的变种 #定义时,在普通方法的基础上添加 @property 装饰器; #定义时,属性仅有一个self参数 #调用时,无需括号 #注意:属性存在意义是:访问属性时可以制造出和访问字段完全相同的假象 class Pager: def __init__(self, current_page): # 用户当前请求的页码(第一页、第二页...) self.current_page = current_page # 每页默认显示10条数据 self.per_items = 10 @property def start(self): val = (self.current_page - 1) * self.per_items return val @property def end(self): val = self.current_page * self.per_items return val p = Pager(1) print(p.start) print(p.end)
创建类的特殊方式 :
def func(self): print ("fdsfd") Foo = type('Foo',(object,), {'func': func}) print(Foo.__dict__)
使用__new__方法和元类方式分别实现单例模式:
__new__方法负责创建一个实例对象,在对象被创建的时候调用该方法它是一 个类方法。__new__方法在返回一个实例之后,会自动的调用__init__方法, 对实例进行初始化。如果__new__方法不返回值,或者返回的不是实例,那么 它就不会自动的去调用__init__方法。
class Foo: def __new__(cls, *args, **kwargs): print("excute __new__") # return object.__new__(cls) return super().__new__(cls) #返回本类的一个实例(必须哟啊返回一个实例) def __init__(self,value): print("excute __init") self.value = value f1 = Foo(1) print(f1.value) f2 = Foo(1) print(f2.value)
单例模式:
单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。
比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 AppConfig 对象的实例,这就导致系统中存在多个 AppConfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似 AppConfig 这样的类,我们希望在程序运行期间只存在一个实例对象。
装饰器实现单例
def Singleton(cls): _instance = {} def _singleton(*args, **kargs): if cls not in _instance: _instance[cls] = cls(*args, **kargs) return _instance[cls] return _singleton @Singleton class A(object): a = 1 def __init__(self, x=0): self.x = x a1 = A(2) a2 = A(3) a1.name = "a1_name" print(a2.name) #a1_name print(a1 == a2) #True
使用模块
class Singleton(object): def foo(self): pass singleton = Singleton() 将上面的代码保存在文件 mysingleton.py 中,要使用时,直接在其他文件中导入此文件中的对象,这个对象即是单例模式的对象 from a import singleton
使用类
import time
import threading
class Singleton(object):
_instance_lock = threading.Lock()
def __init__(self):
pass
# time.sleep(1)
@classmethod
def instance(cls, *args, **kwargs):
if not hasattr(Singleton, "_instance"): #必须加锁,否则多线程无法实现单例
with Singleton._instance_lock:
if not hasattr(Singleton, "_instance"):
Singleton._instance = Singleton(*args, **kwargs)
return Singleton._instance
def task(arg):
obj = Singleton.instance()
print(obj)
for i in range(10):
t = threading.Thread(target=task,args=[i,])
t.start()
time.sleep(20)
obj = Singleton.instance()
print(obj)
基于__new__方法实现(推荐,简单)
import threading class Singleton(object): _instance_lock = threading.Lock() def __init__(self): pass # import time # time.sleep(1) def __new__(cls, *args, **kwargs): if not hasattr(Singleton, "_instance"): # with Singleton._instance_lock: #不加锁也可以实现 if not hasattr(Singleton, "_instance"): Singleton._instance = object.__new__(cls) return Singleton._instance obj1 = Singleton() obj2 = Singleton() print(obj1,obj2) def task(arg): obj = Singleton() print(obj) for i in range(10): t = threading.Thread(target=task,args=[i,]) t.start()
基于metaclass方式实现
相关知识(重要) """ 1.类由type创建,创建类时,type的__init__方法自动执行,类() 执行type的 __call__方法(类的__new__方法,类的__init__方法) 2.对象由类创建,创建对象时,类的__init__方法自动执行,对象()执行类的 __call__ 方法 """
元类的使用
class SingletonType(type): #必须继承type类 def __init__(self,*args,**kwargs): print("第一步") super(SingletonType,self).__init__(*args,**kwargs) def __call__(cls, *args, **kwargs): # 这里的cls,即Foo类 print("第二步",'cls:',cls) obj = cls.__new__(cls,*args, **kwargs) #Foo类实例化的时候先执行类的__new__方法 cls.__init__(obj,*args, **kwargs) #在执行类的__init__方法, return obj class Foo(metaclass=SingletonType): # 指定创建Foo的type为SingletonType def __init__(self,name): print("第四步") self.name = name def __new__(cls, *args, **kwargs): #可以不定制__new__方法,会自动去父类找 print("第三步") return object.__new__(cls) obj = Foo('xx')
实现单例模式
import threading class SingletonType(type): _instance_lock = threading.Lock() # import time # time.sleep(2) def __call__(cls, *args, **kwargs): if not hasattr(cls, "_instance"): #如果有实例对象了,不会再执行__class__方法,就不会执行__init__方法了 # with SingletonType._instance_lock: if not hasattr(cls, "_instance"): cls._instance = super(SingletonType,cls).__call__(*args, **kwargs) print(cls._instance,"--") #执行call 返回的是一个cls(Foo) 实例对象 return cls._instance #表示cls有实例对象,直接返回 class Foo(metaclass=SingletonType): def __init__(self,name): #__init__方法只会加载一次 self.name = name print(self.name) obj1 = Foo('Foo1') obj2 = Foo('Foo2') #创建的还是Foo,__init__不会加载,直接返回obj1的实例 print(obj1,obj2)