facets of objects

Alex Martelli aleaxit at yahoo.com
Wed Oct 25 06:53:09 EDT 2000


<eugene.leitl at lrz.uni-muenchen.de> wrote in message
news:mailman.972467189.13905.python-list at python.org...
>
> (((slightly edited to foil the spambots)))
>
> From: kragen at pobox dot com (Kragen Sitaker)
>
> In Python, it's really simple to create an object that acts like a
> built-in object: a file, a dictionary, a sequence.  You just define the
> methods the built-in object implements --- "implement the protocol" ---
> and everything that expects the built-in object will then be able to
> talk to your object.

Well, *almost* everything.  You cannot use anything but a
built-in dictionary as the namespace in an exec statement,
for example...:

>>> a={}
>>> exec "x=12" in globals(),a
>>> a
{'x': 12}
>>> import UserDict
>>> b=UserDict.UserDict({})
>>> exec "x=12" in globals(),b
Traceback (innermost last):
  File "<pyshell#19>", line 1, in ?
    exec "x=12" in globals(),b
TypeError: exec 2nd/3rd args must be dict or None
>>>


It sure WOULD be nice if there was a way to avoid those few
"real true honest built-in objects needed here!" spots...:-).


> __getattr__ has a more serious problem; it only works for attributes
> that don't really exist.  So if your clients use one of the attribute
> names you used in your implementation --- presumably not knowing you
> used them --- they will get screwed.

This is easily worked around by only using names that start
with __ (and don't end with __) as the real attributes for
"your implementation".  Python handily "decorates" such names
with the classname, making them effectively "private" (in
the sense of avoiding accidental name clashes).  This is not
intended for "security" against _deliberate_ 'cracking'
attempts, though -- that's what bastions &c are for.


> In KeyKOS and EROS, it is common for a single object to implement
> several different interfaces, such as a read-only interface, a
> read-write interface, and a write-only interface; clients holding a
> capability to one interface should not automatically be able to get
> capabilities to other interfaces, although some interfaces will have
> methods that allow a client to request capabilities to other interfaces
> to the same object.

The COM approach is slightly different.  Objects implement several
different interfaces, but there is a standardized way to _request_
another interface (the QueryInterface method that all interfaces
include).  Responding to QI is entirely under control of code in
the object's implementation.

However, there are specific semantic constraints of what an object
is correctly allowed to do in its QI code: in particular, the
success/failure of QI must be commutative -- no "one-way QI"
allowed (abstractly, it's an issue of object-identity; the high
practical significance of it is in enabling certain key optimizations
of roundtrips in distributed object architectures).  So, QI is
not feasible as the implementation of a capability-based permission
system in COM; rather, one uses specific-request-methods, and
returns objects with _distinct_ COM identity if one wants to avoid
the 'reverse request'.


Alex






More information about the Python-list mailing list