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