2012-03-24 11 views
2

ich ein Singleton wie dies umgesetzt haben:Python Singletons Attribut Fehler

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 

I don t __init__ implementieren, da es jedes Mal, wenn ich das Singleton verwenden genannt wird, so um sie zu erhalten, rufe ich einfach initialisieren an der Anfang meines Skripts.

Jedes Mal, wenn ich es laufen:

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

ich diesen Fehler:

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' 

Irgendwelche Ideen, was los ist? Ich benutze einen anderen Singleton und es tut das nicht. Außerdem wird Attr1 gut gedruckt, ich bin sehr verwirrt. Könnte es etwas mit der Benennung zu tun haben, vielleicht hat ein anderer Singleton ein Attribut namens attr2?

EDIT: das Testfall scheint gut zu funktionieren, nachdem es Repo geändert, so ist hier der eigentliche Code

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() 

Schafft diesen Fehler:

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 
+2

Funktioniert für mich. Haben Sie auch einen Fehler mit dem Testfall oder nur im echten Programm? Welche Python-Version? – doublep

+0

nvm, habe gerade den Testfall erneut versucht, scheint gut zu funktionieren (ich habe es von einem anderen Repo gestartet.) –

+0

Python hat ein Designmuster namens [Borg] (http://stackoverflow.com/questions/1318406/why- is-the-borg-pattern-besser-als-das-singleton-pattern-in-python), das oft als besser angesehen wird als Singletons. – katrielalex

Antwort

2

Ihre DataAccessLayer ist eine im alten Stil-Klasse. Versuchen Sie class DataAccessLayer(object): ....

Update:

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.

Quelle: the python reference

+0

Es funktioniert thx :) es ist super und alle, aber jede weitere Erklärung? –

+0

Google "Old-Style-Klassen". – katrielalex

0

leicht off topic, aber ... Dies scheint überhaupt nicht zu mir pythonic. Ich würde versuchen, einen Dekorateur Klasse Singleton, zu schreiben, so kann ich

@Sigleton 
class MySingleton(object): 
    pass 

Sie können auch, wenn schnell jederzeit wieder verwenden tun, wenn Sie sie brauchen, um wieder ...

Hinweis: Es kann kleines Durcheinander in den Metadaten machen (MySingleton ist als Instanz von Singleton, nicht MySingleton), aber vielleicht könnte functools.wraps irgendwie helfen ...