By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
431,990 Members | 1,741 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 431,990 IT Pros & Developers. It's quick & easy.

A problem with some OO code.

P: n/a
TPJ
Help me please, because I really don't get it. I think it's some stupid
mistake I make, but I just can't find it. I have been thinking about it
for three days so far and I still haven't found any solution.

My code can be downloaded from here:
http://www.tprimke.net/konto/PyObject-problem.tar.bz2. There are some
scripts for GNU/Linux system (bash to be precise).

All you need to know is that there are four classes. (Of course, you
may generate all the documentation by typing just "./make_docs". All
you need is Python with Epydoc installed.)

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), it calls the proper method of
its objects' manager (the OManager instance). Details are not important
here, 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).

And now the tests. In the test.py file this is a class called Obj. That
class is just an Object. This is also a class called System1 - this
class is used only to create a more complex system composed of many
objects and one objects' manager.

You can run all the tests by just typing "./test" in console (or a
terminal emulator). I'm still getting the same error:

--------------------------------------------------
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'
--------------------------------------------------

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). As the result,
the "demandNewLink" method of the object "objA" is called. This method
calls the "_makeNewLink" method of the objects' manager, and this
method calls the "_makeLinkSafe" method of the object, that demanded a
new link. The last method, called "__makeNewLink" (so this is a
so-called private method), is called then. This last method is supposed
to check if the link was really demanded and then make it "safe" by
placing the information about this link in the proper dictionary
(__ls_existing_links).

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*.

I even wrote a simple program to test the usage of the so-called
private fields in Python classes:

--------------------------------------------------
class A( object ):
def __init__( self ):
self.__a = 1
def _add( self ):
print "self.__a =", self.__a
self.__a += 1
def print_a( self ):
print self.__a

class B( A ):
def __init__( self ):
A.__init__( self )
self.__b = 2
def print_b( self ):
print self.__b

def test():
o = B()
o.print_a()
o.print_b()
o._add()
o.print_a()
o.print_b()
--------------------------------------------------

The code works just as I thought it should work: all is fine here. The
B class instance (the b object) is able to refer to the so-called
private field of the A class (through a A-class method, that was
inherited by the class B).

Why I can't do the same thing in test.py and in PyObject.py?

I just don't get it.

(And sorry for the subject of this topic. I really had no better
idea...)

Feb 4 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
> AttributeError: 'Obj' object has no attribute
'_Object__ls_demanded_links'
--------------------------------------------------

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). As the result,
the "demandNewLink" method of the object "objA" is called. This method
calls the "_makeNewLink" method of the objects' manager, and this
method calls the "_makeLinkSafe" method of the object, that demanded a
new link. The last method, called "__makeNewLink" (so this is a
so-called private method), is called then. This last method is supposed
to check if the link was really demanded and then make it "safe" by
placing the information about this link in the proper dictionary
(__ls_existing_links).

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*.


I didn't find any place where you create your __ls_demanded_links-list.
So - how do you expevct it to be found, __-semantics or not?

But I _did_ find a self.__ls_demandedLinks. So I guess you got confused
in your variable names.
After changing that, I got some other errors.

So basically this boils down to some simple spelling errors. You migt
want to think about using pychecker or pylint or both, and a
auto-completion-capable editor like eric or (x)emacs.

Diez
Feb 4 '06 #2

P: n/a
On Sat, 04 Feb 2006 04:21:50 -0800, TPJ wrote:
Help me please, because I really don't get it. I think it's some stupid
mistake I make, but I just can't find it. I have been thinking about it
for three days so far and I still haven't found any solution.

My code can be downloaded from here:
http://www.tprimke.net/konto/PyObject-problem.tar.bz2. There are some
scripts for GNU/Linux system (bash to be precise).
Hint: when asking strangers to help you, at THEIR time and expense, with
no offer to recompense them for their efforts, it is up to YOU to make
their job as easy as possible.

That means don't expect people to download some untrusted, potentially
dangerous, piece of code from a stranger on Usenet, go to the trouble of
extracting it from an archive, and then debug it for you.

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've made some comments based on the information in your post. If they
don't help, you will need to spend some time creating a short example that
has the same problem. 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.

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

(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?
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?

This is the normal Python idiom for testing whether an object exists
(strictly speaking, whether a name is bound to an object).

try:
some_object
except NameError:
print "some_object does not exist"

Is that what you mean?
it calls the proper method of
its objects' manager (the OManager instance). Details are not important
here,
I bet the details are absolutely vital.

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?

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.
And now the tests. In the test.py file this is a class called Obj. That
class is just an Object.
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.
This is also a class called System1 - this
class is used only to create a more complex system composed of many
objects and one objects' manager.

You can run all the tests by just typing "./test" in console (or a
terminal emulator). I'm still getting the same error:

--------------------------------------------------
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.

(Aside: generic names like "Obj" or "Object" are poor practice unless they
genuinely are generic. A good name should be self-documenting if possible,
but more importantly, names which are easy to confuse like Obj and Object
should be avoided.)

If you want to work with Object instances, why not just use them instead
of passing around strings that represent them?
As the result,
the "demandNewLink" method of the object "objA" is called. This method
calls the "_makeNewLink" method of the objects' manager, and this
method calls the "_makeLinkSafe" method of the object, that demanded a
new link. The last method, called "__makeNewLink" (so this is a
so-called private method), is called then.
This seems like a very brittle way to code.
This last method is supposed
to check if the link was really demanded and then make it "safe" by
placing the information about this link in the proper dictionary
(__ls_existing_links).
Huh? Do you mean that there is a way for links (whatever they are) to be
requested without calling demandNewLink? How would this happen?

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.

Thus:

class Parrot:
__plumage = "red"

actually creates a class attribute "_Parrot__plumage". If you know the
name of the class, you can bypass Python's "private attributes".

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.

Now, the consequences:

When Python does a lookup, it looks in the appropriate namespace for a
name. Except for special rules relating to inheritance, Python doesn't
magically look up attributes in another object's namespace just because
that attribute was defined as a private attribute elsewhere. See below for
the consequences.
I even wrote a simple program to test the usage of the so-called
private fields in Python classes:
Good. Now how about getting a simple program that demonstrates your
problem?

class A( object ):
def __init__( self ):
self.__a = 1
def _add( self ):
print "self.__a =", self.__a
self.__a += 1
def print_a( self ):
print self.__a
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.
class B( A ):
def __init__( self ):
A.__init__( self )
self.__b = 2
def print_b( self ):
print self.__b

def test():
o = B()
o.print_a()
o.print_b()
o._add()
o.print_a()
o.print_b()
I don't think this is showing what you think it is showing. Private vs
public attributes just get in the way: they work *exactly* the same in
Python except for name mangling. This is the problem bit:

class B( A ):
def __init__( self ):
A.__init__( self ) ### LOOK HERE

You aren't creating an A instance here, you are calling A.__init__ with a
first argument of "self", which is a B instance. __init__ does not create
instances, it runs AFTER the instance is already created.

Perhaps you already know that. But I don't think you understand the
consequences of this, when using so-called private attributes:

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.

That means that B methods that access self.__b will work, because the name
mangling rules work *with you*, and self.__b is mangled to self._B__b. But
B methods that access self.__a will NOT work, because it is mangled to
self._B__a, and that attribute does not exist.

(However, that is not your problem.)

The code works just as I thought it should work: all is fine here.
Except it is brittle and hard to maintain.
The
B class instance (the b object) is able to refer to the so-called
private field of the A class (through a A-class method, that was
inherited by the class B).

Why I can't do the same thing in test.py and in PyObject.py?
Here is your exception again:
line 582, in __makeLinkSafe
i = self.__ls_demanded_links.index( s_object )
AttributeError: 'Obj' object has no attribute
'_Object__ls_demanded_links'


This is not making sense to me. If self is an instance of Obj, the
name-mangling rules will convert self.__ls_demanded_links to
self._Obj__ls_demanded_links. The only thing I can guess is that somehow,
somewhere, you have tried to manually set the class of an object.

Something like this perhaps?
class Obj: .... __bar = "nothing"
.... class Object(Obj): .... __foo = "something"
.... def foo(self):
.... print self.__foo
.... def bar(self):
.... print self.__bar
.... x = Object()
x.__class__.__name__ = "Obj"
x.foo() something x.bar()

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 6, in bar
AttributeError: Obj instance has no attribute '_Object__bar'

That's the only way I can think of to get such an unusual error.

--
Steven.

Feb 4 '06 #3

P: n/a
TPJ
Thank you VERY much!

These other errors are not so serious. I think I'll fix them soon. The
most important thing is that now I'm ready to work on that code again.
Life is beautiful again!

Damn, I knew it is some very stupid mistake. I must learn how to use
that pylint, instead of asking people on the web such a stupid
questions.

(The sad thing is that I'm the only one developer, who works on that
code. I think I had just stuck before I sent the first message in this
topic.)

Feb 4 '06 #4

P: n/a
TPJ
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.

Feb 4 '06 #5

P: n/a
TPJ wrote:
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.


The pont of the exercise of taking non-working code and trying to cut
away parts that aren't part of the problem is to isolate where the
problem is. This is especially true in dynamic languages like Python,
where problems usually consist of something not being what you expected
it to be, but it's true in all other languages as well.

Even if it means creating a standalone program that's a simplified
version of the particular logic that's failing, this is good. It makes
it easy for others to find where the problem is without having to tangle
through your other (working) code.

But in my view this is only the side benefit. The _real_ benefit is
that a very significant fraction of the time, going through this
exercise will actually help _you_ figure out your problem on your own.
Taking a tangle of code that isn't working for reasons you don't
understand and then pulling out threads to see where the problem is so
you can show it to someone else to get help will usually allow _you_ to
see where the problem was in the process.

--
Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
God said: "Let Newton be"; and all was light.
-- Alexander Pope
Feb 4 '06 #6

P: n/a
On 4 Feb 2006 09:51:22 -0800
"TPJ" <tp*****@interia.pl> wrote:
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.


"Object" in fact means *exactly* the same thing in Python
that it does in any other OOP language. The only issue is
that *anything*, even simple things like integers, are
*objects* in Python. So, saying "object" (versus something
else) doesn't mean much that we didn't already know -- if
the program can manipulate it, then it's an "object".

Saying a "class instance" or just "instance" for short is a
way of specifically saying that it is a *user defined
object* that we are talking about, created from a "class"
(of course the "class" is *also* an object, and you can even
make objects that make classes -- I think that's what a
"metaclass" is, though I get fuzzy past that point). Usually
the point, though, is to draw attention to what class it is
an instance of.

A class *is* probably describable as a "template" for an
object, although the word "template" has a technical
meaning, too, IIRC, which might not be totally consistent
with that. More to the point, though, classes are "instance
factories" in Python. It's almost as if a class is nothing
more than a special category of functions that return
instances.

I don't know if I've helped at all, but I hope so. ;-)

Cheers,
Terry

--
Terry Hancock (ha*****@AnansiSpaceworks.com)
Anansi Spaceworks http://www.AnansiSpaceworks.com

Feb 6 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.