<previous | top | next> Pyro Manual

6. Rules and Limitations

Pyro's hierarchical object naming scheme

Brief: it's just like a filesystem with directories and files, and path separators.
Verbose: Pyro's object naming is hierarchical. Let's call the full set of names the namespace. A namespace has a single root that contains all other names. A name in the namespace is the name of a group or an object. A group can contain other groups, and objects. The root is a group.

Object names can be absolute or relative. Relative object names are searched in the default group (which has a special name, set by PYRO_NS_DEFAULTGROUP). Absolute names are always searched from the root. Absolute object names start with a special character that signifies the root (set by PYRO_NS_ROOTCHAR). Relative object names don't have this character at the start.

Object names can be simple or compound. Compound object names consist of multiple parts separated by a special group separator character, set by PYRO_NS_GROUPSEP. Compound names are used to search within the namespace hierarchy. Each component of the name is the name of a group. The last name component can be the name of a group or an object (usually the latter).

Let's finish with a few examples to clarify all this. Note that by default, the root character is ':' and the group separator is '.'. Note that by name alone you cannot distinguish a group name or an object name.
: The namespace root group
:TestObj The TestObj name in the root (most likely an object name)
:Test.simple.object1 The object1 name in the simple group in the Test group in the root.
Test.simple.object1 The object1 name in the simple group in the Test group in the default group (which is ":Default" if not configured otherwise. This is the Default group in the root).
object1 The object1 name in the default group.

Usage rules and guidelines

You should follow the following guidelines when using Pyro.
  1. The remote class can't have a remote __init__ method. You should use a regular initialization method which you must call explicitly after binding to the remote object. The __init__ method will only be called on the server side when the object is created.
  2. You can only call remote methods. There is (currently) no such thing as direct member access on the remote object. If you try to do this on a static proxy, you'll get an AttributeError exception. If you try to do this on a dynamic proxy, you get a bogus result. It is unlikely there will ever be a 'remote __getitem__'-sortof thing because the (dynamic) Pyro proxy already uses the __getitem__ method to intercept method calls. Furthermore, I favor the getter/setter style of programming known from Java, where no direct member access is used. All member access is done through getter and setter methods.
  3. The proxy compiler can't yet generate proxies for the classes in a module if it's passed on the command line as a member of a Python package ('Package.module').
  4. The class which is actually instantiated in the server should inherit from Pyro.core.ObjBase. You could define a new (probably empty) class in the server which inherits both from Pyro.core.ObjBase and the class which is made remotely available. This approach is used in the example in the next chapter. See also the next item.
  5. You could also use the Delegation pattern instead of subclassing from Pyro.core.ObjBase. This works as follows: create an object of your remote class, create a Pyro.core.ObjBase object, and tell the latter to use the former as delegate:
    ...
    impl = MyRemoteClass()
    obj = Pyro.core.ObjBase()
    obj.delegateTo(impl)
    ...
    
    and you then connect obj to the Daemon.
  6. Note that, because Python doesn't do this automatically, you have to call the __init__ from the base class in the __init__ method -if you have one- of your remote class:
    def __init__(self):
        Pyro.core.ObjBase.__init__(self)
        ...
  7. Funny and unexpected things happen if you try to use a Pyro proxy object in various statements such as while obj:. Like the limitation with direct member access, this is also caused by the way the proxy object is currently implemented. It intercepts each and every method call. And testing for zero-ness or nonzero-ness or coercion are also method calls! (__nonzero__, __coerce__ etc.)