我的单身汉不喜欢

2024-09-27 21:29:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个单件.py,其代码如下:

from functools import wraps

def singleton(cls):
    instances = {}

    @wraps(cls)
    def getinstance(*args, **kw):
        if cls not in instances:
            instances[cls] = cls(*args, **kw)
        return instances[cls]
    return getinstance

@singleton
class OTConn():
    def __init__(self):
        self.conn = None

我有一个test01.py:

from app04 import singleton

ot_conn = singleton.OTConn()

ot_conn.conn = "a"

test02.py

import singleton

ot_conn = singleton.OTConn()

print (ot_conn.conn)  # there print: None

我在一个进程中运行test01.pytest02.py,但是ot_conn.conn打印None。你知道吗


编辑

我试着把代码改成:

@singleton
    class OTConn():
        conn = None
        def __init__(self):
            pass

还是不行。有朋友能帮我介绍一下单身汉的装修方法吗?你知道吗


编辑-2

看这个singleton method

装饰方法和我的一样。你知道吗


Tags: instances代码frompyimportselfnonedef
1条回答
网友
1楼 · 发布于 2024-09-27 21:29:32

似乎您还不了解如何使用singleton装饰器。您错误地认为用singleton装饰的类变成了singleton属性。它没有。你知道吗

下面是一个如何工作的例子。请注意,我稍微修改了singleton的定义,以除去一些瑕疵。它只适用于python3。如果您需要在python3中使用这个decorator,则必须放回一些残羹剩饭。你知道吗

from functools import wraps

def singleton(cls):
    instance = None
    @wraps(cls)
    def getinstance(*args, **kwds):
        nonlocal instance
        if instance is None:
            instance = cls(*args, **kwds)
        return instance
    return getinstance

# Check that it works ... first use the decorator on a class definition
@singleton
class Foo:
    pass

# Now instantiate the class twice ...
a = Foo()
b = Foo()

# ... and verify that we have only one instance.
assert a is b

Python的is操作符验证对象标识。assert a is b确认ab是同一个实例。你知道吗

下面是如何验证它的工作方式是否更像您在测试代码中尝试执行的操作:

# Showing how it works with your example
@singleton
class OTConn:
    # Your class variable `conn` and constructor were completely
    # irrelevant, so I leave them out
    pass

ot_conn_a = OTConn()
ot_conn_a.conn = 'a'

ot_conn_b = OTConn()
assert ot_conn_b.conn == 'a'

您的代码和我的代码之间最重要的区别是singleton.OTConn没有出现在我的代码中的任何地方。它不可能工作!(除非有一些代码您没有向我们展示,这使得它可以工作。)

如何观察singleton正常工作的分步说明

你所报告的行为,以及你一直拒绝确切描述你认为你是如何在一个进程中执行这段代码的,给人一种强烈的印象,你是在不同的进程中执行这段代码的。正如许多人向您指出的那样,在这种情况下,您的单例类不可能工作。你知道吗

在这里,我给你一个逐步的方法,如何观察singleton在多个模块中正常工作,而不是一个进程。你知道吗

步骤1:创建一个目录(文件夹),您将在其中创建以下python源文件。你知道吗

步骤2:在步骤1中创建的目录中创建一个名为singleton.py的文件,其中包含以下代码:

def singleton(cls):
    instance = None
    @wraps(cls)
    def getinstance(*args, **kwds):
        nonlocal instance
        if instance is None:
            instance = cls(*args, **kwds)
        return instance
    return getinstance

第3步:在同一目录中创建一个名为theclass.py的文件,其中包含代码

from singleton import singleton

@singleton
class TheClass:

    def __init__(self):
        self.conn = None

步骤4:同样,在同一个目录中创建一个名为client1.py的文件,其中包含

from theclass import TheClass

instance = TheClass()
print("In client1.py instance.conn =", instance.conn)
instance.conn = 'XXXX'
print("In client1.py instance.conn =", instance.conn)

第五步:。。。还有一个名为client2.py的文件,包含

from theclass import TheClass

instance = TheClass()
print("In client2.py instance.conn =", instance.conn)

步骤6:您需要的最后一个文件应该被称为main.py并包含

from client1 import instance as i1
from client2 import instance as i2

print("In main.py i1.conn =", i1.conn)
print("In main.py i2.conn =", i2.conn)

i2.conn = 'YYY'

print("In main.py i1.conn =", i1.conn)
print("In main.py i2.conn =", i2.conn)

第七步:执行main.py

步骤8:观察输出

In client1.py instance.conn = None
In client1.py instance.conn = XXXX
In client2.py instance.conn = XXXX
In main.py i1.conn = XXXX
In main.py i2.conn = XXXX
In main.py i1.conn = YYY
In main.py i2.conn = YYY

从输出中可以看出

  • TheClass在两个独立的模块中实例化。你知道吗
  • 实例的conn属性以None开头
  • 将此属性的值设置为'XXXX'会将其设置为两个实例。你知道吗
  • 将该属性的值设置为'YYY',这一次使用其他实例这样做,再次更改两个实例。你知道吗

不可避免的结论是singleton像广告宣传的那样工作。但这确实关键地依赖于两个实例在同一过程中。你知道吗

相关问题 更多 >

    热门问题