At first I'd like to thank you for such a long answer.

> (...)
> You need to simplify the code as much as possible, cutting away everything
> you can, to the SMALLEST amount of code that still experiences the problem.

I understand your POV and I really appereciate your reply, but I doubt
that I could simplify my code to make it small *enough* to fit in one
post and not look too long.

BTW: is there some safety way to show long piece of code on a
group like comp.lang.python? Uploading my code to my website was the
first (and the only one...) idea I had.

> (...)
> There is very little point in showing us test code
> that works -- your problem isn't with code that works, it is with code
> that doesn't work.

You see - that's one of my problems. I'm working on my PyObject module
(it is intended to be a base for more complex systems). For now
there are no other modules, that use PyObject. So the test.py module,
that consists of some test for my module, is the *only* piece of code
that I could show you. That's all the story.

> > All you need to know is that there are four classes.
>
> No, I'm sure we need to know much more than that.

Yes, you're right. But I tried to explain my problem as easily as
possible. And (as I thought) only four classes were involved.

> > (Of course, you
> > may generate all the documentation by typing just "./make_docs". All
> > you need is Python with Epydoc installed.)
>
> Oh right, well just let me rush off and install Epydoc just for you, okay?

It was not my intention to ask you to install anything for me. I just
thought, that someone might be interested to read some documentation
about the module, that causes the problem. I think it's easier to read
documentation of more complex system, than just code.

Perhaps it's about my English (I'm still studying) - a language easy
to learn, but difficult to master. By "you may" I meant "you might, if
you'd like to (for some reasons)", not "you are expected to do it".

> > In the PyObject.py there are two classes: Object and OManager. When
> > Object wants to know if some link is safe (in another words: it wants
> > to know if some another object exists),
>
> What is a link in your application? What do you mean "another object"?
> Like an int or a string?

1) In OO vocabulary, class is something like template for an object.
But I think the word "object" has something different meaning in
Python. In general I don't use the word "object" in the same meaning,
that it is used by Python. I try to use words in the same way, that
they
are used in OO.
Sometimes I use the word "class" to talk about template (for an
object), and the word "instance" to talk about an object of some class,
but the only reason I do it is to distinguish between OO-object and
Python-object.

2) Link is something like address (like a post address). My module -
in general - is just a template of a system of objects, that are able
to communicate with each other. All that an object needs to communicate
with an another object, is the name of that another object - it's
adress
(my assumption is that the names of the objects will be unique).
"Link" to an another object is just the name of that object.

> > it calls the proper method of
> > its objects' manager (the OManager instance). Details are not important
> > here,
>
> I bet the details are absolutely vital.

Yes, they are - were. But I didn't want to describe my code in details
in my post. I suspected, that there's some stupid mistake somewhere in
my code. The truth is, all I wanted was someone else to take a look at
this code.

(BTW - I was right. My problem was caused by a spelling mistake, and
someone found it. And it made me feel very stupid, but I think I
deserved
it.)

> > so I'll just say, that if the link is safe, the objects' manager
> > calls the proper method of the object, that sent him request. This
> > method of the object just stores the information about that link (that
> > it's safe), in the so-called private field (the fields used to store
> > the information about the links are called __ls_existing_links and
> > __ls_demanded_links).
>
> This is a terribly involved way of doing it, and I'm not even sure what
> "it" is that you are trying to do. Are you trying to do some sort of
> dispatch mechanism?

My idea is as follows:
1) There's one objects' manager, that manages all the objects in some
system.
2) Every object has its unique name, and is registered with the
objects' manager.
3) When an object-sender wants to send a message to some
object-receiver, all that the object-sender has to do is to tell the
objects' manager, what's the name of the object-receiver.

The only problem is that the object-sender has no idea if the
object-receiver exists.

A situation, when object-receiver doesn't exist, shouldn't happen, but
as long as code is written by people, such a mistake can be done.
Therefore I developed a mechanism, that may prevent such a situation.

Every object-sender must create a link to the object-receiver. A link
is just the name (id) of the object-receiver. There's only one
OO-object in the system, that knows, if the object-receiver exists.
It's the objects' manager. So the object-sender "asks" its objects'
manager, if the link from that object-sender to the object-receiver is
"safe" (in another words: if the object-receiver exists). If the
object-receiver exists, the objects' manager just informs the
object-sender (that might be also called the object-requester), that
the link is safe (and can be used).

But if the object-receiver doesn't exist, the objects' manager doesn't
inform the object-requester about anything.

Now, there are two different scenarios, that might happen:

a) The object-receiver will be created - this is the desired
situation. When the object-receiver will be registered with the
objects' manager, the objects' manager will inform the
object-requester, that the object-receiver exists and the link is
safe.

b) The object-receiver won't be created. Because the object-requester
tracks all the demanded links, it knows, that not all of these links
are safe - and therefore it knows, that it's not ready to work. In the
final version of the module, the objects' manager will be able to
check, if there are any objects, that aren't ready to work. In such a
case the whole system just won't work (and it'll explain the
developer why).

It's not so complicated, and I suppose it will help me to create less
error-prone code in the future.

> I see you have a line "i = self.__ls_demanded_links.index( s_object )". It
> looks like you are storing your data in a chunk of text, and then running
> index on that text to find the bit you want to work with. If you wanted to
> do that much work, just write your script in bash and be done with it!
> Python has lists and dicts and other advanced data structures. Use them.
> You will be glad.

The reason, why a list was used in this case, is now obsolete and it
will probably change in the future.

But, in general, you're right. The dictionary would be much better in
this case even in the previous version of my module.

And... I know how great are lists, dicts and tuples. That's the reason
I threw out Java, C++ and (in most cases) C, and fell in love with
Python. In my personal opinion the adventure with Python begins in the
moment, when you realize, how easy are lists, dicts and tuples to use.
(Yes, I know, there are also sets, but I don't use them at all. So
far...)

> So Obj is an alias for Object? What's an Object? Is it the same as the
> Python built-in type "object"?
>
> But later on you say:
>
> "All these methods are the methods of the Object class (defined in
> PyObject.py), not of the Obj class (defined in test.py)."
>
> So Object and Obj are not the same.

No. I think that the declaration of the Obj class will explain
everything:

class Obj( Object ):
  ...

So the Obj class is an *extension* of the Object class. Therefore I
wrote that "Obj is just an Object". I (mis?)used the vocabulary from
OO: something may *be* a kind of something else (inheritance), or it
may *has* something else (composition). But I'm not sure about those
words; I have read many books in Polish, not in English.

> > --------------------------------------------------
> > Traceback (most recent call last):
> >   File "test.py", line 142, in test04CreateSystems
> >     system1 = System1()
> >   File "test.py", line 81, in __init__
> >     self.objA.demandNewLink( 'B' )
> >   File "/home/tpj/opt/Praca/Programy/PyObject/workdir/PyObject.py",
> > line 503, in demandNewLink
> >     s_object )
> >   File "/home/tpj/opt/Praca/Programy/PyObject/workdir/PyObject.py",
> > line 800, in _makeNewLink
> >     o_srcobj._makeLinkSafe( s_target )
> >   File "/home/tpj/opt/Praca/Programy/PyObject/workdir/PyObject.py",
> > line 608, in _makeLinkSafe
> >     self.__makeLinkSafe( s_object )
> >   File "/home/tpj/opt/Praca/Programy/PyObject/workdir/PyObject.py",
> > line 582, in __makeLinkSafe
> >     i = self.__ls_demanded_links.index( s_object )
> > AttributeError: 'Obj' object has no attribute
> > '_Object__ls_demanded_links'
>
> [snip]
>
> > Perhaps I'll explain what's going on there. First, the objects' manager
> > is created, and then also some objects are created. After doing that,
> > the object called "objA" demands a new link to the other object, called
> > "objB" (this is the line 81 in the error message above).
>
> Your description does not match what line 81 actually says. It says:
>
> self.objA.demandNewLink('B')
>
> self (an instance of System1, not Obj or Object) grabs the attribute
> called "objA", and calls its method demandNewLink with an argument of
> the string 'B', not objB an instance of Obj or Object.

It's a typo, it should be 'B' instead of "objB".

In fact, the reference to the object "B" is self.objB - I think that's
the reason for this mistake.

> If you want to work with Object instances, why not just use them instead
> of passing around strings that represent them?

Well, I *don't* want to work with any instances, therefore I intend to
give all the objects unique names.

> (...)
> Huh? Do you mean that there is a way for links (whatever they are) to be
> requested without calling demandNewLink? How would this happen?

Well - it's Python, so *anything* can be done with any so-called
private attributes. Therefore such a possibility exists.

But it's not intended to be used in such a way. In "normal" use it's
impossible to request a link without calling demandNewLink method.

Perhaps my explanation wasn't too clear.

> > All these methods are the methods of the Object class (defined in
> > PyObject.py), not of the Obj class (defined in test.py). According to
> > my knowledge about the OO programming Python should be able to realize,
> > that the so-called private fields, that are being referred from these
> > Object class methods, are the private fields of the *Obj class
> > instance*, not of the *Object class one*.
>
> Some serious confusion here.
>
> What are fields? Do you mean attributes? I'm going to assume that you do.
>
> Would it help if I told you that Python doesn't have private attributes?
> It *simulates* private attributes using name mangling.

1) "Fields" - yes, I think I should have written attributes. Sorry for
that, my problem is that the only books about OO that I have read were
in Polish, so my vocabulary might be incorrect.

In general, every object has methods (functions, procedures, etc.) and
- I think - attributes (variables).

2) I know that Python has no private *anything*, and therefore I
called it "so-called private".

> (...)
> PLEASE don't bother to tell us how Python sucks because it doesn't have
> "real private attributes", we've heard the arguments (and the abuse) fifty
> times before.

Python's not sucks, I find it the best programming language in the
world. It suits all my needs.

Believe me or not, but I have argued for Python to be (one of) the
best language(s) to write OO applications. Since I have started coding
in
Python, I found that the idea of private, protected and public
attributes/methods may be as well the matter of *convention*, as real
*mechanism*.

Anyway, I don't find Python inferior to any other OO language just
because Python have no *real* private methods/attributes.

So, I think, we're both on the same side.

> (...)
>
> Good. Now how about getting a simple program that demonstrates your
> problem?
>
> (...)
>
> Do you enjoy all this make-work, writing tedious methods to get or set or
> print attributes? I suggest you ditch all the private attributes and just
> make them public. You've already spent three days hitting your head
> against a brick wall because of excessive data-hiding. Was it worth it?
> Python is a language that encourages the attitude "We're all adults here"
> -- getters/setters are discouraged.

Maybe I'll make it clear: I wrote this simple example to show *myself*,
that I'm not out of my mind. It was supposed to be *very* simple. I
just
wanted to check, if I'll be able to change the so-called private
attribute declared in the A class by calling a method declared in
another class. That's all. I think that if I hadn't done it, I would
have started to doubt, that 2 + 2 = 4.

Why I did such a obvious test? Because I thought that it was my
problem in the PyObject module: the need to change a so-called private
attribute declared in the class Object by calling a method of another
class (an instance of another class, to be precise).

> (...)
>
> The call to A.__init__ creates an attribute __a to self. Remember, self is
> an instance of B (not A). Apply the name-mangling rules, which are applied
> at compile time: the code in A's method mangles __a to _A__a. So
> A.__init__ creates an attribute _A__a in B's namespace. So B has two
> attributes, _A__a and _B__b.
>
> (...)
>
> (However, that is not your problem.)

So it works just as it's supposed to work.

All right, now I'm OK. My madness has gone.

> (...)
>
> Here is your exception again:
>
> (...)

Well, I decided to cut out all the rest - because (I think) it has
nothing to do with my code - and therefore with my problem.

Once again - thank you for such a long and thorough answer. Once again
- sorry for some mistakes that I made in my first message, especially
for those "fields" (I feel really silly now). I wrote the first
message in the state of madness, after spending *three* days on
analysis of my code, without any progress. I was very frustrated, and
my explanations could be incomprehensible.

-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to