189 8069 5689

python函数单例 python 单例类

python类里面的函数怎么单例

# mysingleton.py

成都创新互联是一家集网站建设,秦皇岛企业网站建设,秦皇岛品牌网站建设,网站定制,秦皇岛网站建设报价,网络营销,网络优化,秦皇岛网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。

class My_Singleton(object):

def foo(self):

pass

my_singleton = My_Singleton()

将上面的代码保存在文件 mysingleton.py 中,然后这样使用:

from mysingleton import my_singleton

请教Python 使用装饰器实现单例模式的原理

简单来讲,可以不严谨地把Python的装饰器看做一个包装函数的函数。 比如,有一个函数: def func(): print 'func() run.' if '__main__' == __name__: func() 运行后将输出: func() run. 现在需要在函数运行前后打印一条日志

python类的继承和单例模式 singleton、运算符重载

@[toc]

全局只有一个实例

font color=#03a3e3 该实现方式在多线程场景下不安全

继承其他类的类称为派生类(derived class)

被其他类继承的类称为这些类的基类(base

class)

需要注意圆括号中基类的顺序:font color=#03a3e3 从左到右搜索 font

多继承会导致菱形 diamond关系:有至少一个基类可以从子类经由多个继承路径到达

基类方法可能被多次调用

防止重复访问,每个基类只调用一次

通过子类实例对象课调用父类已被覆盖

慎用多继承(二义性)

– 对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型

– 运算符重载不能改变其本来寓意

– 运算符重载只是一种 “语法上的方便” (sugar)

– 是一种函数调用的方式

Python如何实现单例模式

有些时候你的项目中难免需要一些全局唯一的对象,这些对象大多是一些工具性的东西,在Python中实现单例模式并不是什么难事。以下总结几种方法:

使用类装饰器

使用装饰器实现单例类的时候,类本身并不知道自己是单例的,所以写代码的人可以不care这个,只要正常写自己的类的实现就可以,类的单例有装饰器保证。

def singleton(cls):

instances = {}

def _wrapper(*args, **kwargs):

if cls not in instances:

instances[cls] = cls(*args, **kwargs)

return instances[cls]

return _wrapper

你会发现singleton装饰器内部使用了一个dict。当然你也可以用其他的方式,不过以下的实现是错误的:

def singleton(cls):

_instance = None #外部作用域的引用对于嵌套的内部作用域是只读的

def _wrapper(*args, **kwargs):

if _instance is None: #解释器会抛出"UnboundLocalError: ...referenced before assignment"

_instance = cls(*args, **kwargs) #赋值行为使解释器将"_instance"看作局部变量

return _instance

return _wrapper

使用元类(__metaclass__)和可调用对象(__call__)

Python的对象系统中一些皆对象,类也不例外,可以称之为”类型对象”,比较绕,但仔细思考也不难:类本身也是一种对象,只不过这种对象很特殊,它表示某一种类型。是对象,那必然是实例化来的,那么谁实例化后是这种类型对象呢?也就是元类。

Python中,class关键字表示定义一个类对象,此时解释器会按一定规则寻找__metaclass__,如果找到了,就调用对应的元类实现来实例化该类对象;没找到,就会调用type元类来实例化该类对象。

__call__是Python的魔术方法,Python的面向对象是”Duck type”的,意味着对象的行为可以通过实现协议来实现,可以看作是一种特殊的接口形式。某个类实现了__call__方法意味着该类的对象是可调用的,可以想像函数调用的样子。再考虑一下foo=Foo()这种实例化的形式,是不是很像啊。结合元类的概念,可以看出,Foo类是单例的,则在调用Foo()的时候每次都返回了同样的对象。而Foo作为一个类对象是单例的,意味着它的类(即生成它的元类)是实现了__call__方法的。所以可以如下实现:

class Singleton(type):

def __init__(cls, name, bases, attrs):

super(Singleton, cls).__init__(name, bases, attrs)

cls._instance = None

def __call__(cls, *args, **kwargs):

if cls._instance is None

# 以下不要使用'cls._instance = cls(*args, **kwargs)', 防止死循环,

# cls的调用行为已经被当前'__call__'协议拦截了

# 使用super(Singleton, cls).__call__来生成cls的实例

cls._instance = super(Singleton, cls).__call__(*args, **kwargs)

return cls._instance

class Foo(object): #单例类

__metaclass__ = Singleton

a = Foo()

b = Foo()

a is b

True

a.x = 1

b.x

1

使用__new__

__init__不是Python对象的构造方法,__init__只负责初始化实例对象,在调用__init__方法之前,会首先调用__new__方法生成对象,可以认为__new__方法充当了构造方法的角色。所以可以在__new__中加以控制,使得某个类只生成唯一对象。具体实现时可以实现一个父类,重载__new__方法,单例类只需要继承这个父类就好。

class Singleton(object):

def __new__(cls, *args, **kwargs):

if not hasattr(cls, '_instance'):

cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)

return cls._instance

class Foo(Singleton): #单例类

a = 1


名称栏目:python函数单例 python 单例类
转载注明:http://jkwzsj.com/article/doggpso.html

其他资讯