Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用python限制类实例的数量_Python_Class_Pyqt_Instance_Py2exe - Fatal编程技术网

使用python限制类实例的数量

使用python限制类实例的数量,python,class,pyqt,instance,py2exe,Python,Class,Pyqt,Instance,Py2exe,Μy main类创建一个简单的QmainWindows,如下所示: class mcManageUiC(QtGui.QMainWindow): def __init__(self): super(mcManageUiC, self).__init__() self.initUI() def initUI(self): self.show() def main(): app = QtGui.QApplication(sy

Μy main类创建一个简单的
QmainWindows
,如下所示:

class mcManageUiC(QtGui.QMainWindow):
    def __init__(self):
        super(mcManageUiC, self).__init__()

        self.initUI()

    def initUI(self):
        self.show()
def main():
    app = QtGui.QApplication(sys.argv)
    renderManagerVar = mcManageUiC()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()
在我的文件末尾,我像这样启动它:

class mcManageUiC(QtGui.QMainWindow):
    def __init__(self):
        super(mcManageUiC, self).__init__()

        self.initUI()

    def initUI(self):
        self.show()
def main():
    app = QtGui.QApplication(sys.argv)
    renderManagerVar = mcManageUiC()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()
我的问题是,每次我找到它时,它都会启动一个新窗口。 我想知道是否有一种方法可以检测脚本中是否存在以前的类实例(以便关闭旧实例或避免启动新实例),或者是否有其他解决方案

另外,在使用py2exe编译代码时,Windows上的.exe文件也存在同样的问题;它每次都会启动一个新窗口。我是否可以在setup.py中添加一些内容,使Windows不会像这样运行

有可能吗?如果有,怎么可能


注意:我正在使用Windows 7 64位与eclipse一起编译。

您可以独占一个套接字

import socket
try:    
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except:
    "Network Error!"

s.settimeout(30)
try:
    s.connect(('localhost' , 123))
except:
    "could not open...already in use socket(program already running?)"
不知道这是否是一个好方法,但我在过去使用过它,它解决了这个问题

这是为了防止在程序已经运行时启动程序,而不是在生成多个窗口的单个脚本中启动新窗口…

使用类变量:

class mcManageUiC(QtGui.QMainWindow):
    singleton = None
    def __init__(self):
        if not mcManageUiC.singleton: #if no instance yet
            super(mcManageUiC, self).__init__()

            self.initUI()
            ...
            mcManageUiC.singleton = self
        else: 
            ...


    def initUI(self):
        self.show()

有几种方法可以做到这一点,您可以使用Class属性来存储所有实例——如果这样做,您可能希望通过weakref模块将它们存储为弱引用,以防止垃圾收集问题:

class MyClass(object):
    _instances=[]
    def __init__(self):
        if(len(self._instances) > 2):
            self._instances.pop(0).kill() #kill the oldest instance
        self._instances.append(self)

    def kill(self):
        pass #Do something to kill the instance
不过这有点难看。您可能还需要考虑使用某种工厂(条件地)创建一个新实例。这种方法更一般一些

import weakref
class Factory(object):
     def __init__(self,cls,nallowed):
         self.product_class=cls  #What class this Factory produces
         self.nallowed=nallowed  #Number of instances allowed
         self.products=[]

     def __call__(self,*args,**kwargs):
         self.products=[x for x in self.products if x() is not None] #filter out dead objects
         if(len(self.products) <= self.nallowed):
             newproduct=self.product_class(*args,**kwargs)
             self.products.append(weakref.ref(newproduct))
             return newproduct
         else:
             return None

#This factory will create up to 2 instances of MyClass
#and refuse to create more until at least one of those 
#instances have died.
factory=Factory(MyClass,2)   
i1=factory("foo","bar")      #instance of MyClass
i2=factory("bar","baz")      #instance of MyClass
i3=factory("baz","chicken")  #None
导入weakref
类工厂(对象):
定义初始化(self、cls、nallowed):
self.product_class=cls#这家工厂生产什么级别的产品
self.nallowed=nallowed#允许的实例数
self.products=[]
定义调用(self,*args,**kwargs):
self.products=[x为self.products中的x,如果x()不是None]#过滤掉死对象

如果(len(self.products)只需添加一个计数器,就可以限制要在代码中创建的实例数:

class A(object):
 ins = 0 # This is a static counter
 def __init__(self):
  if A.ins >= 1: # Check if the number of instances present are more than one. 
   del self
   print "Failed to create another instance" #if > 1, del self and return.
   return
  A.ins += 1
  print "Success",str(self)
尝试通过以下方式运行:

lst = []
for i in range(1,101):
 a=A()
 lst.append(a)

这些是独立的进程吗?都在同一个file.py文件中,我正在尝试将def main放在一个单独的file.py文件中,但这是一种创建独立进程的方法吗?为什么是-1?如果你给我一个负分,请用主要缺点进行评论…这将适用于使用py2exe的冻结实例…如果你需要选择一个通常打开…[编辑]啊,我没有注意到他在同一个脚本中启动了多个实例…在这种情况下,我相信有更好的方法可以工作,但在windows 7中套接字是不好的,你必须在防火墙中添加一个规则才能使用你想要的每个套接字。默认情况下,有几个是打开的…如果你选择其中一个你很好(我用的是3322466),从你的本地主机那里比从外部主机那里更开放connection@Pooya--谢谢。我实际上用过这种东西。我有数据文件(每个大约5 GB)抽象在一个类中,该类在读取数据时存储数据。我的工厂获取文件名,确定它是否已打开,并返回打开的数据文件的句柄(如果存在),否则我将创建一个新的数据文件。它工作得很好。所有引用都以weakref形式存储在工厂中,以便在我关闭后不会留下500mb的数据文件。这太神奇了,你是如何为你的数据文件实现weakref的?@Pooya——使用
weakref.ref
更新了工厂示例。在我的数据文件示例中,我使用dict而不是列表来存储产品。然后检查数据文件是否仍然有效就很简单了。
datafile=d[fname]如果((d中的fname)和(d[fname])不是无))else DataFileObject(fname,*args,**kwargs)
我尝试了第一个解决方案,它应该可以工作,但是,我使用的是Eclipse,是否有可能每次重新源化类并忘记类属性时Eclipse都会创建一个新的进程?@Ennakard--Eclipse应该无关紧要(如果有,这是一个需要修复的巨大错误).在你的问题中,你说“我的问题是,每次我找到它”——你说“每次我找到它”是什么意思?