2012-03-24 3 views
2

У меня есть синглтон реализована следующим образом:Python одноточечно атрибут ошибки

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 

Я не; т реализовать __init__, поскольку она вызывается каждый раз, когда я использовать синглтон, так, чтобы вокруг него, я просто называю инициализации в начало моего скрипта.

Всякий раз, когда я запустить его:

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

Я получаю эту ошибку:

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?

EDIT: TestCase, кажется, работает нормально после того как я изменил репо, так вот фактический код

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

Создает эту ошибку:

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

Работает для меня. Испытываете ли вы неудачу с тестовым чехлом или только в реальной программе? Какая версия Python? – doublep

+0

nvm, попробовал тест снова, кажется, работает нормально (я запускал его из другого репо.) –

+0

Python имеет шаблон дизайна, называемый [Borg] (http://stackoverflow.com/questions/1318406/why- is-the-borg-pattern-better-than-the-singleton-pattern-in-python), который часто считается более аккуратным, чем одиночные. – katrielalex

ответ

2

Ваш DataAccessLayer является классом старого стиля. Попробуйте 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.

Источник: the python reference

+0

Это работает thx :) его удивительный и все, но какое-либо дальнейшее объяснение? –

+0

Google «классы старого стиля». – katrielalex

0

Немного не по теме, но ... Это не кажется вещим мне вообще. Я хотел бы попробовать написать декоратор класс Singleton, так что я могу сделать

@Sigleton 
class MySingleton(object): 
    pass 

Вы также можете повторно использовать, если быстро в любое время, если вам это нужно снова ...

Примечания: Это может сделать небольшой беспорядок в метаданных (MySingleton является примером Singleton, а не MySingleton), но, возможно, functools.wraps может помочь как-то ...

Смежные вопросы