2015-05-29 82 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()的唯一方法。 –

相關問題