python - 如何使用 Pyro 代理对象作为工厂?

标签 python factory-pattern pyro

我想将 Pyro 与一组涉及工厂模式的现有类一起使用,即 A 类的对象(通常只有其中一个)用于实例化 B 类的对象(可以是任意的这些)的数量)通过工厂方法。因此,我将 A 类对象公开为 Pyro 代理对象。

我扩展了火焰兵 introductory sample code大致反射(reflect)我正在尝试做的事情。服务器端代码如下:

# saved as greeting.py
import Pyro4
import socket

class NewObj:
    func_count = None
    def __init__(self):
    print "{0} ctor".format(self)
        func_count = 0
    def __del__(self):
    print "{0} dtor".format(self)
    def func(self):
    print "{0} func call {1}".format(self, self.func_count)
    self.func_count += 1

class GreetingMaker(object):
    def __init__(self):
    print "{0} ctor".format(self)
    def __del__(self):
    print "{0} dtor".format(self)
    def get_fortune(self, name):
    print "getting fortune"
        return "Hello, {0}. Here is your fortune message:\n" \
               "Behold the warranty -- the bold print giveth and the fine print taketh away.".format(name)
    def make_obj(self):
    return NewObj()

greeting_maker=GreetingMaker()

daemon=Pyro4.Daemon(host=socket.gethostbyname(socket.gethostname()), port=8080)                                      # make a Pyro daemon
uri=daemon.register(greeting_maker, "foo")  # register the greeting object as a Pyro object

print "Ready. Object uri =", uri            # print the uri so we can use it in the client later
daemon.requestLoop()                        # start the event loop of the server to wait for calls

客户端代码也略有改动:

# saved as client.py
import Pyro4

uri="PYRO:foo@10.2.129.6:8080"
name="foo"

greeting_maker=Pyro4.Proxy(uri)          # get a Pyro proxy to the greeting object
print greeting_maker.get_fortune(name)   # call method normally
print greeting_maker.make_obj()

我的意图是能够创建 NewObj 的实例并像我可以在客户端操作 GreetingMaker 的实例一样操作它们,但它看起来好像发生的事情是当 make_obj 方法被调用时,一个 NewObj 在服务器端创建,立即超出范围,因此被垃圾收集。

这是输出的样子,服务器端:

<__main__.GreetingMaker object at 0x2aed47e01110> ctor
/usr/lib/python2.6/site-packages/Pyro4-4.12-py2.6.egg/Pyro4/core.py:152: UserWarning: HMAC_KEY not set, protocol data may not be secure
  warnings.warn("HMAC_KEY not set, protocol data may not be secure")
Ready. Object uri = PYRO:foo@10.2.129.6:8080
getting fortune
<__main__.NewObj instance at 0x175c8098> ctor
<__main__.NewObj instance at 0x175c8098> dtor

...和客户端:

/usr/local/lib/python2.6/dist-packages/Pyro4-4.12-py2.6.egg/Pyro4/core.py:152: UserWarning: HMAC_KEY not set, protocol data may not be secure
  warnings.warn("HMAC_KEY not set, protocol data may not be secure")
Hello, foo. Here is your fortune message:
Behold the warranty -- the bold print giveth and the fine print taketh away.
Traceback (most recent call last):
  File "client.py", line 9, in <module>
    print greeting_maker.make_obj()
  File "/usr/local/lib/python2.6/dist-packages/Pyro4-4.12-py2.6.egg/Pyro4/core.py", line 146, in __call__
    return self.__send(self.__name, args, kwargs)
  File "/usr/local/lib/python2.6/dist-packages/Pyro4-4.12-py2.6.egg/Pyro4/core.py", line 269, in _pyroInvoke
    data=self._pyroSerializer.deserialize(data, compressed=flags & MessageFactory.FLAGS_COMPRESSED)
  File "/usr/local/lib/python2.6/dist-packages/Pyro4-4.12-py2.6.egg/Pyro4/util.py", line 146, in deserialize
    return self.pickle.loads(data)
AttributeError: 'module' object has no attribute 'NewObj'

我怀疑我可以通过让工厂类(即 GreetingMaker)保留对它创建的每个 NewObj 的引用并添加一个清理方法来解决这个问题某种……但这真的有必要吗?我是否在 Pyro 中遗漏了一些可以帮助我实现这一点的东西?

(为清楚起见进行了编辑)

最佳答案

我最近遇到了 this feature并且正在使用它。这对我使用类似工厂模式的代码至关重要。

Pyro 服务器

class Foo(object):
    def __init__(self, x=5):
        self.x = x

class Server(object):
    def build_foo(self, x=5):
        foo = Foo(x)
        # This line will register your foo instance as its own proxy
        self._pyroDaemon.register(foo)
        # Returning foo here returns the proxy, not the actual foo
        return foo

#...
uri = daemon.register(Server()) # In the later versions, just use Server, not Server()
#...

关于python - 如何使用 Pyro 代理对象作为工厂?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9655695/

相关文章:

python - 如何从Python字典中的一对(父,子)恢复路径?

python - 采购 python 脚本

python - 用正确的方法包装Pyro的NameServer

python - 根据从 python 中的其他两个字符串列应用的条件创建一个新列

python - 一般删除所有字符串字段的空格 - SQLAlchemy

c++ - 具有抽象参数的抽象工厂?

mongodb - DDD 和 MongoDB : Is it okay to let Mongo create ObjectIDs?

c# - 抽象工厂模式而不是泛型——怎么样?

python - 我如何编写装饰器来将某些内容包装在带参数的上下文管理器中?

pyrocms - 在 PyroCMS 主题中包含 css 和 javascript