Python2.7:使用局部变量作为参数在运行时创建方法
我的示例使用QT,但在其他上下文中肯定也很有用 在下面的示例中,Export类的create函数在运行时创建一些函数,作为参数和局部变量传递。当按下QT GUI上的按钮时,将调用这些函数:Python2.7:使用局部变量作为参数在运行时创建方法,python,qt,python-2.7,methods,factory,Python,Qt,Python 2.7,Methods,Factory,我的示例使用QT,但在其他上下文中肯定也很有用 在下面的示例中,Export类的create函数在运行时创建一些函数,作为参数和局部变量传递。当按下QT GUI上的按钮时,将调用这些函数: try: from PyQt4 import QtGui,QtCore from PyQt4.QtGui import * from PyQt4.QtCore import * except : raise Exception("failed to import QT. I
try:
from PyQt4 import QtGui,QtCore
from PyQt4.QtGui import *
from PyQt4.QtCore import *
except : raise Exception("failed to import QT. Is it installed ?")
import time,copy
class Export(QTableWidget):
class Field:
def __init__(self,name):
self.name = name
def __init__(self):
self.fields = []
def add(self,name):
self.fields.append(self.Field(name))
def create(self,export_function):
QTableWidget.__init__(self,len(self.fields),3)
for index,field in enumerate(self.fields):
self.setItem(index,0,QTableWidgetItem(field.name))
editable_widget = QTableWidgetItem("0")
self.setItem(index,1,QTableWidgetItem(editable_widget))
print "creating export function: ",field.name,editable_widget
def export(field_name=field.name,widget=editable_widget):
print "export ",field_name,widget
value = widget.text()
export_function(field_name,value)
export_button = QtGui.QPushButton('set', self)
export_button.clicked.connect(export)
self.setCellWidget(index,2,export_button)
class Export_Qt(QMainWindow):
def __init__(self,parent=None):
QMainWindow.__init__(self, parent)
main_widget = QWidget(self)
layout = QVBoxLayout(main_widget)
export = Export()
export.add("A")
export.add("B")
def export_function(field,value): print field,":",value
export.create(export_function)
layout.addWidget(export)
main_widget.setLayout(layout)
self.setCentralWidget(main_widget)
self.resize(500,350)
if __name__ == '__main__' :
app = QApplication([])
main_window = Export_Qt(parent=None)
main_window.show()
try:
while True:
main_window.update()
QApplication.processEvents()
time.sleep(0.05)
except KeyboardInterrupt: pass
except Exception as e : print e
令我惊讶的是,事情有一半起作用。将显示GUI,控制台将打印:
creating export function: A <PyQt4.QtGui.QTableWidgetItem object at 0x7fef87c9e9e0>
creating export function: B <PyQt4.QtGui.QTableWidgetItem object at 0x7fef87c9ec20>
export False <PyQt4.QtGui.QTableWidgetItem object at 0x7fef87c9ec20>
False : 0
创建导出函数:A
创建导出函数:B
然后,如果我按下“B”对应的按钮,控制台将打印:
creating export function: A <PyQt4.QtGui.QTableWidgetItem object at 0x7fef87c9e9e0>
creating export function: B <PyQt4.QtGui.QTableWidgetItem object at 0x7fef87c9ec20>
export False <PyQt4.QtGui.QTableWidgetItem object at 0x7fef87c9ec20>
False : 0
导出错误
错:0
所以,如果我期望的是“B”,则打印为“False”。但是请注意,QTableWidgetItem的地址是正确的,因此这种方法似乎是有意义的
使用rapid fix的解决方案会很好,但如果答案也能提供一些关于python如何工作的见解,我会非常高兴
注意:我知道只有一个name属性的类字段没有意义。这是因为上面的代码简化了我使用的真实代码。为了便于阅读。这项工作:
class Export(QTableWidget):
class Field:
def __init__(self,name):
self.name = name
def __init__(self):
self.fields = []
self.editable_widgets = []
def add(self,name):
self.fields.append(self.Field(name))
def _create(self,field_index,export_function):
self.setItem(field_index,0,QTableWidgetItem(self.fields[field_index].name))
editable_widget = QTableWidgetItem("pouet")
self.editable_widgets.append(editable_widget)
self.setItem(field_index,1,editable_widget)
print "creating export function: ",self.fields[field_index].name,editable_widget,editable_widget.text()
def export():
print "export ",field_index,self.fields[field_index].name,self.editable_widgets[field_index]
export_function(self.fields[field_index].name,self.editable_widgets[field_index].text())
export_button = QtGui.QPushButton('set', self)
export_button.clicked.connect(export)
self.setCellWidget(field_index,2,export_button)
def create(self,export_function):
QTableWidget.__init__(self,len(self.fields),3)
for index in range(len(self.fields)):
self._create(index,export_function)
这是有道理的。离开create函数后,字段不再是有效地址。所以field_name=field.name没有意义。
另一方面,这个小部件仍然存在(在QT中的某个地方进行管理),因此它可以正常工作
在上面的解决方案中,我确保我指向了一些在保留create之后仍然存在的东西。为什么要使用嵌套类?你真的需要吗?可能会给您一些解释。@iled我想使用嵌套类向最终用户(包括我自己)隐藏内部构件。通过仅公开导出,我可以自由地以我想要的方式修改字段。话虽如此,为了清楚起见,我应该调用class_字段。您也可以通过继承来实现这一点。我认为这将提高它的可读性和可维护性。一般来说,您的代码很难阅读。避免长行(最多79个字符)并使用更多的空白。给你指引。同样重要的是,考虑到这里难以阅读的张贴代码会吓跑读者(和答案)。不管怎样,很高兴你自己解决了这个问题,并发布了解决方案!