2015-05-29 128 views
0

我正在使用zerorpc构建pub-sub NAT断路器,并在昨天完成。现在我试图修改我的代码,以便通过使用Sander Marechal的code sample将发布者作为守护程序运行。如何在类方法中调用不同的类实例?

这里是我的publisher.py

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

import zerorpc 
import os, sys, time 
from daemon import Daemon 

class publisherd(Daemon): 
    def run(self): 
     publisher = zerorpc.Publisher() 
     publisher.bind("tcp://0.0.0.0:8888") 

     # Start RPC Server 
     s = LocalForwarder() 
     s.bind("tcp://0.0.0.0:4242") 
     s.run() 

class LocalForwarder(zerorpc.Server): 
    def pub(self, domain, testcase_pk, testresult_pk): 
     print domain, testcase_pk, testresult_pk 
     publisher.add(domain, testcase_pk, testresult_pk) 
     print 'Send to dispacher' 

if __name__ == "__main__": 
    daemon = publisherd('/tmp/publisher.pid') 
    if len(sys.argv) == 2: 
     if 'start' == sys.argv[1]: 
      daemon.start() 
     elif 'stop' == sys.argv[1]: 
      daemon.stop() 
     elif 'restart' == sys.argv[1]: 
      daemon.restart() 
     else: 
      print "Unknown command" 
      sys.exit(2) 
     sys.exit(0) 
    else: 
     print "usage: %s start|stop|restart" % sys.argv[0] 
     sys.exit(2) 

我建立一个autosender.py测试

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
import zerorpc 
import os, sys 

time = 0 
sleep = 10 

for i in range(1,10,1): 

    ts_dispatcher_name = "KS-1" 
    testsuite_id = i 
    tr_pk = time 

    c = zerorpc.Client() 
    c.connect("tcp://127.0.0.1:4242") 
    c.pub(ts_dispatcher_name, testsuite_id, tr_pk) 
    print ts_dispatcher_name, testsuite_id, tr_pk 

    time += sleep 
    os.system("sleep %s" %sleep) 

,但我得到以下错误味精测试时:

File "publisher_d.py", line 21, in pub 
publisher.add(domain, testcase_pk, testresult_pk) 
NameError: global name 'publisher' is not defined 

它似乎LocalForwarder不能识别发布者实例,但我无法弄清楚为什么发生错误?我该如何纠正这个错误?

回答

0

你必须出版商实例传递给你的LocalFowarder实例,即:

class Publisherd(Daemon): 
    def run(self): 
     publisher = zerorpc.Publisher() 
     publisher.bind("tcp://0.0.0.0:8888") 

     # Start RPC Server 
     s = LocalForwarder(publisher) 
     s.bind("tcp://0.0.0.0:4242") 

     s.run() 

class LocalForwarder(zerorpc.Server): 
    def __init__(self, publisher, *args, **kw): 
     super(LocalForwarder, self).__init__(*args, **kw) 
     self.publisher = publisher 

    def pub(self, domain, testcase_pk, testresult_pk): 
     print domain, testcase_pk, testresult_pk 
     self.publisher.add(domain, testcase_pk, testresult_pk) 
     print 'Send to dispacher' 
+0

感谢您的回复:)您的解决方案看起来不错,但它会刷新原来的zerorpc.Server class _init_?我是否需要将zerorpc源代码复制到此处? –

+0

哦,我明白了,* args&** kw将会完成这项工作....我将在这里运行测试tommrrow早上&报告。感谢您的帮助〜:) –

+0

对'super(LocalForwarder,self).__ init __()'的调用负责'zerorpc.Server'的正确初始化 - 我用'* args,** kw'来通用当然我们可以通过任何可选的参数。请注意,我使用'zerorpc'的零经验(没有双关语),所以我不能保证你的代码能正常工作,但至少这会解决你当前的问题。正如附注:错误消息应该转到'sys.stderr',而不是'sys.stdout'(这是'print'的默认值,您可能也想看一下标准库的'logging'模块 –

0

它看起来像你期望发布者是一个全局变量。为了实现这个目标,你需要尝试这样的:

my_global = None 

def x(): 
    global my_global 
    my_global = 1 

def y(): 
    print(my_global) 

默认情况下,您创建的出版商VAR是局部范围以该方法 - 这是在分配的缺省值。关键字global允许您在全局范围级别设置该变量。仅引用该值的函数不需要global关键字。

+0

为什么要使用一个全球性的时候,你可以通过将变量作为自变量避免呢? –

+0

我没有评论他的程序结构/风格 - 只是为什么他试图做的不工作。 –

+0

这不起作用,因为名称'publisher'没有在方法中定义 - 正如你所解释的那样 - 但这并不意味着OP“预计”这个名称是全局的,并且更多地表明它并不意味着使用全局变量是使这个对象可用于LocalForwarder.pub()的唯一方法。 –

相关问题