Python单例属性错误

Python singleton attribute error

我有一个这样的单例实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Test123(object):        
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Test123, cls).__new__(cls, *args, **kwargs)
        return cls._instance

    def initialize(self):
        self.attr1 = 500
        self.attr2= 0
        self.attr3= 0.10

    def printit(self):
        print self.attr1
        print self.attr2
        print self.attr3

我不实现uu init_uuu,因为每次使用singleton时都会调用它,所以为了绕过它,我只在脚本开始时调用initialize。

每当我运行它时:

1
2
3
Test123().initialize()
time.sleep(1)
Test123().printit()

我得到这个错误:

1
2
3
4
5
6
7
Traceback (most recent call last):
  File"Z:\test\test123.py", line 22, in <module>
500
    Test123().printit()
  File"Z:\test\test123.py", line 17, in printit
    print self.attr2
AttributeError: 'Test123' object has no attribute 'attr2'

你知道怎么回事吗?我用的是另一个单件,它不这样做。另外,ATTR1打印得很好,我很困惑。它可能与命名有关,也许其他的单例有一个名为attr2的属性?

编辑:在我更改了repo之后,测试用例似乎工作正常,所以这里是实际的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    import MySQLdb

class DataAccessLayer():
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(DataAccessLayer, cls).__new__(cls, *args, **kwargs)
        return cls._instance

    def initialize(self):
        #init local connection
        self.dalConnection = 0
        try:
            self.dalConnection = MySQLdb.connect('localhost', 'root', 'awesomepassword', 'arb');

        except MySQLdb.Error, e:
            print"Error %d: %s" % (e.args[0],e.args[1])

    def __del__(self):
        self.dalConnection.close()


    def addrow(self):
        try:
            cur = self.dalConnection.cursor()


            cur.close()
            self.dalConnection.commit()

        except MySQLdb.Error, e:
            print"Error %d: %s" % (e.args[0],e.args[1])

DataAccessLayer().initialize()
DataAccessLayer().addrow()

创建此错误:

1
2
3
4
5
6
7
Traceback (most recent call last):
  File"Z:\test\DataAccess.py", line 36, in <module>
    DataAccessLayer().addrow()
  File"Z:\test\DataAccess.py", line 25, in addOption
    cur = self.dalConnection.cursor()
AttributeError: DataAccessLayer instance has no attribute 'dalConnection'
Exception AttributeError:"DataAccessLayer instance has no attribute 'dalConnection'" in <bound method DataAccessLayer.__del__ of <__main__.DataAccessLayer instance at 0x00000000022A2748>> ignored


你的DataAccessLayer是一个老式的班级。试试class DataAccessLayer(object): ...

更新:

Class Types

Class types, or"new-style classes," are callable. These objects normally act as factories for new instances of themselves, but variations are possible for class types that override __new__(). The arguments of the call are passed to __new__() and, in the typical case, to __init__() to initialize the new instance.

Classic Classes

Class objects are described below. When a class object is called, a new class instance (also described below) is created and returned. This implies a call to the class’s __init__() method if it has one. Any arguments are passed on to the __init__() method. If there is no __init__() method, the class must be called without arguments.

源:python引用


稍微偏离主题,但是…这对我来说一点也不像Python。我想写一个装饰类singleton,这样我可以

1
2
3
@Sigleton
class MySingleton(object):
    pass

如果您再次需要它,您还可以在任何时候快速重用它…

注意:它可能会在元数据中造成一些小混乱(mysingleton是singleton的实例,而不是mysingleton),但functools.wrapps可能会有所帮助…