Python在整个模块中创建单个实例

时间:2015-03-05 13:15:40

标签: python python-2.7

我正在开发一个python模块。我的模块需要不同时间从数据库中获取数据。我正在编写一个数据层类,其唯一的动机是编写所有在同一个地方命中DB的函数,并从我的模块的不同方法调用这些数据层类方法。

我尝试了以下代码:

class datalayer:
   cur = None;     #Cursor which would be used by all methods
   def __init__(self):
     conn=sqlite3.connect(DB_NAME);
     cur=conn.cursor();

   def getEmpData(self,flowId):
     sql= "Select * from emp"
     cur.execute(sql);
     rows = cur.fetchall(); 
     return rows;

   def getManData(self,flowId):
     sql= "Select * from manager"
     cur.execute(sql);
     rows = cur.fetchall(); 
     return rows;

一旦完成,我将在我想要命中DB的类中创建相同类的实例,例如:

class example1:
  def ex1():
    do_something()
    datalayerInstance =  datalayer();
    datalayerInstance.getEmpData();

但即使每次创建数据层类的实例时都会创建一个新的游标对象。我想避免这种情况,只创建一个游标对象,并在类中使用相同的对象。如何实现这一目标?

另外,我尝试使用静态方法,但这也没有解决我的问题。

请帮助我,因为我不熟悉Python。

4 个答案:

答案 0 :(得分:2)

datalayer.py

datalayerInstance =  datalayer();

def get_datalayerinstance():
    return datalayerInstance

example.py

import datalayer
datalayerInstance = get_datalayerinstance();

答案 1 :(得分:1)

你想要一个单身人士

Creating a singleton in python

class Singleton(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

class Logger(object):
    __metaclass__ = Singleton

http://python-3-patterns-idioms-test.readthedocs.org/en/latest/Singleton.html

class OnlyOne:
    class __OnlyOne:
        def __init__(self, arg):
            self.val = arg
        def __str__(self):
            return repr(self) + self.val
    instance = None
    def __init__(self, arg):
        if not OnlyOne.instance:
            OnlyOne.instance = OnlyOne.__OnlyOne(arg)
        else:
            OnlyOne.instance.val = arg
    def __getattr__(self, name):
        return getattr(self.instance, name)

答案 2 :(得分:0)

您似乎没有将光标设置为初始化方法中datalayer类的属性。

class DataLayer(object):
    cur = None

    def __init__(self):
        if DataLayer.cur is None:
            conn = sqlite3.connect(DATABASE)
            DataLayer.cur = conn.cursor()

    def get_employee_data(self, flow_id):
        sql = "Select * from emp"
        self.cur.execute(sql);
        return self.cur.fetchall(); 

我将您的示例中的一些名称更改为python中更接受的标准。需要注意的是,此示例在并发环境中使用是不安全的。

答案 3 :(得分:-1)

你想要的是一个单身人士。为此,您可以覆盖__new__,以便每次创建新的datalayer对象时,它都使用相同的游标。

class datalayer(object):
    _cur = None;     #Cursor which would be used by all methods

    def __new__(cls, *args, **kwargs):
        if not cls._cur:
            conn=sqlite3.connect(DB_NAME);
            cls._cur = conn.cursor();
        return cls._cur

   def getEmpData(self,flowId):
     sql= "Select * from emp"
     cls._cur.execute(sql);
     rows = cls._cur.fetchall(); 
     return rows;

   def getManData(self,flowId):
     sql= "Select * from manager"
     cls._cur.execute(sql);
     rows = cls._cur.fetchall(); 
     return rows;

它应该可以工作,虽然它可能不是最漂亮的方式,但还有其他更简单和优雅。
唯一的好处是,这不需要您更改所有代码。

  

根据这一点改编的答案:https://stackoverflow.com/a/1810367/2549230