Pyro4返回POD对象后访问属性报错,如何直接使用其字段?
Ah, I see the issue here! The problem is that even though you've marked your POD class with @Pyro4.expose, Pyro4 doesn't automatically expose instance attributes like self.a by default. The class-level @expose decorator only makes methods accessible remotely, not direct attribute access.
Let's go through two straightforward fixes for this:
Solution 1: Expose attributes using properties
The cleanest way to expose your a attribute is to wrap it in a @property decorator and ensure that property is exposed. This gives you control over what's accessible and allows you to add logic later if needed:
import Pyro4 @Pyro4.expose class POD: def __init__(self): self._a = 1 # Use a private backing variable @property @Pyro4.expose # Expose the property getter def a(self): return self._a @Pyro4.expose class Source: def get(self): p = POD() daemon.register(p) return p daemon = Pyro4.daemon() ns = Pyro4.locateNS() uri = daemon.register(Source) ns.register('test_obj', uri) daemon.requestLoop()
Now when you access o.a in your client code, it will call the exposed property getter method behind the scenes, which Pyro4 recognizes as an exposed method.
Solution 2: Enable automatic attribute exposure
If you want all instance attributes of your exposed classes to be accessible remotely without writing properties, you can enable Pyro4's EXPOSE_ATTRIBUTES configuration option. This is a quicker approach but be careful—it will expose all attributes, including any you might not intend to make public:
Add this line at the top of your server code:
Pyro4.config.EXPOSE_ATTRIBUTES = True
Your original POD class will work as-is with this setting. Pyro4 will automatically handle attribute access for any class marked with @Pyro4.expose.
Testing the fix
Either way, your client code should now work without throwing that error:
import Pyro4 s = Pyro4.Proxy('PYRONAME:test_obj') o = s.get() print(o.a) # This will output 1 as expected!
Just a quick note: When returning the POD instance from Source.get(), calling daemon.register(p) is actually optional—Pyro4 will automatically register exposed objects returned from remote methods. But keeping it in doesn't hurt anything.
内容的提问来源于stack exchange,提问作者Tom

