python----面向对象

 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)
原文地址:https://www.cnblogs.com/yanxiaoge/p/10497744.html