Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.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_Loops_Callback_Twisted - Fatal编程技术网

Python 一次又一次的扭曲矩阵回调调用

Python 一次又一次的扭曲矩阵回调调用,python,loops,callback,twisted,Python,Loops,Callback,Twisted,我需要的是,当用户单击一个按钮时,该按钮启动回调并向她传递一些参数,每次参数都会不同 我查看了文档,但似乎缺少用于循环的部分: Looping A common form of dependency is needing to perform the asynchronous operation all over again. The canonical example of this an HTTP redirect: when the callback for a deferred fro

我需要的是,当用户单击一个按钮时,该按钮启动回调并向她传递一些参数,每次参数都会不同

我查看了文档,但似乎缺少用于循环的部分:

Looping

A common form of dependency is needing to perform the asynchronous operation all over again. The canonical example of this an HTTP redirect: when the callback for a deferred from a page request is returned, it could be the result, or it could be an empty body with the Location HTTP header set, in which case you simply perform the operation over again.

[ here is the HTTP redirect example. It also should have pictures. ]
if在工作,try也在工作,但是回调只运行一次

 if happen this:
  try:
     print "I'm here!"
     myobjectx.addCallback(test,x,y,z)  
     myobjectx.callback()

  except:
     ...
只是为了了解这是如何工作的:

1) create the myobject that do  nothing for now 
2) when an event is fired prepare the callback for the myobject e execute it 
3) how can I redo the callback next time the event happen again?
我正在查看异步客户端的pymodbus库示例:

我有两个文件:

MAINPROCESS
MODBUSLIB
我打电话给你

myobjectx = MODBUSLIB.protocol.ClientCreator(reactor, ModbusClientProtocol
        ).connectTCP("localhost", Defaults.Port)
然后在由if触发的函数中:

if ('Gigiisclicked' in existkeys):

      myobjectx.addCallback(beginAsynchronousTest)
      myobjectx.callback(beginAsynchronousTest)
      print "executed"

这就是,当事件发生时,打印会一次又一次地重复,但是回叫号是。

我认为这里的一个误解是关于如何使用
延迟的
实例

您应该将
延迟
视为具有两种不同的(尽管高度相关)用途

一个用途是能够从一些代码中发布事件,这些代码知道如何注意到事件已经发生在其他可能有兴趣知道事件已经发生的代码中

此用法的一个示例是
ClientCreator.connectTCP
:此API的实现知道TCP连接尝试何时成功(或失败),并使用
延迟的
将此信息发布到其他代码。像这样使用Deferred的代码实际上是实例化Deferred(例如,d=Deferred())的代码,之后使用Deferred.callbackDeferred.errback

Deferred
的另一个用途是允许对发生的事件感兴趣的代码了解这些事件已经发生。例如,您的应用程序需要TCP连接以交换数据,但需要在设置TCP连接时等待,然后才能继续。像这样使用Deferred的代码是使用Deferred.addCallbackDeferred.addErrback(在Twisted的最新版本中也是Deferred.cancel)的代码

Deferred.addCallback
是一个API,用于指定当
Deferred
最终得到结果时要运行的代码

Deferred.callback
是用于将结果提供给
Deferred
的API。而且,重要的是,
延迟的
只能给出一个结果。每个延迟的
实例表示单个操作的完成或单个事件的发生

有一些例外情况和一些进一步的微妙之处,但一个很好的经验法则是,如果您的代码没有实例化
延迟
,那么您的代码就不应该使用其
回调
(或
errback
)方法。调用其中一个是为创建延迟的
的任何代码调用的作业

有鉴于此,我希望很明显,在这段代码中使用
延迟的
API存在一些需要解决的问题:

myobjectx = MODBUSLIB.protocol.ClientCreator(reactor, ModbusClientProtocol
    ).connectTCP("localhost", Defaults.Port)

...

if ('Gigiisclicked' in existkeys):

    myobjectx.addCallback(beginAsynchronousTest)
    myobjectx.callback(beginAsynchronousTest)
    print "executed"
最直接的是,您不应该在这里调用
myobjectx.callback
。这就是
ClientCreator.connectTCP
的工作(最重要的是,
beginAsynchronousTest
可能没有意义,因为这
延迟了

相反,我认为您希望使用
ModbusClientProtocol
实例的方法,该实例最终将为您创建
ClientCreator.connectTCP
。在链接到的示例中,请注意,
beginAsynchronousTest
被定义为接受一个名为
client
的参数

由于
beginAsynchronousTest
被传递给
ClientCreator.connectTCP
返回的
Deferred
addCallback
方法,这意味着将使用初始化
ClientCreator
的协议实例调用它(在这种情况下,
ModbusClientProtocol
)<只要
ClientCreator
的实现给出了延迟的
的结果,就会调用code>beginAsynchronousTest
——换句话说,一旦建立了连接,就会调用它。建立TCP连接需要多少时间,因为它涉及到通过任意网络链接与任意其他计算机交换数据-不知道这些资源完成连接设置所需的时间

一旦调用了
beginAsynchronousTest
,您就有了一个连接-由传递给它的
ModbusClientProtocol
实例表示。这是程序中的一个点,在这个点上,您可以开始执行多个操作(例如,每次单击一个按钮时都执行一些操作)

此时,您的程序开始时使用的
Deferred
(在上面的代码片段中称为
myobjectx
)已完成,不再有用或有趣,因此您将不再使用它

相反,您将调用
ModbusClientProtocol
read\u-coil
write\u-coil
或任何您想要执行的操作)的方法。这些方法中的每一个都可能返回一个全新的
Deferred
,表示特定操作的结果。您需要使用
addCallback
来了解它们的结果

人们经常遇到的另一个问题是如何进行这些额外的方法调用。如果您要将代码添加到
beginAsynchronousTest
的主体中,那么如何操作就相当简单:

reading = client.read_coils(1, 1)
但是,我怀疑您不想将按钮处理代码添加到
beginAsynchronousTest
的主体中。相反,您可能在程序的其他地方有一个事件处理程序,在按下按钮的任何时候都会调用它。幸运的是,处理这种情况并不复杂

关键是要记住,任何时候只要你有一个连接的引用,你就会
class ButtonModbusSomething(object):
    def __init__(self):
        self.client = None

    def connect(self):
        creator = MODBUSLIB.protocol.ClientCreator(reactor, ModbusClientProtocol)
        connecting = creator.connectTCP("localhost", Defaults.Port)
        connecting.addCallback(self._connected)
        connecting.addErrback(log.err)

    def _connected(self, client):
        self.client = client

    def buttonClicked(self, existkeys):
        if self.client is not None:
            if "Gigiisclicked" in existkeys:
                self.client.read_coil(1, 1)