On State and Behavior: To understand objects in terms of state and behavior you need to absolve yourself from implementation details of languages and think at an abstract level.
Take a button object, for example. It has state and behavior. Possible states may include, is_active, is_focused, is_mapped, etc. Behavior is what the button does when it responds to events, (e.g when you click on it, or drag it, or position a pointer over it.) If you've done any form of event based programming (GUI/Games/Simulation), this method of thinking becomes natural. As you can see, when I'm designing a button object, I don't care what Python does with is_active. I don't care how it accesses. I don't care what is_active means to Python. I don't care about Python's __get__ /__set__ special/latent functions or implementation details. is_active to me and every other developer is a state of the button object. And at that level that's all that matters. Python can tell me it's just ones and zeros for all I care. In very well designed systems, the state of an object should only be changed by the object. For example, a third party randomly changing is_active, (which Python lets you do freely and easily) from False to True may crash your GUI. And I'm not making this up. Things like this do really happen depending on the whackyness of your toolkit. So sometimes, it is my duty to protect the state of an object. Especially if its state cannot afford to be corrupted rendering the system unstable. And situations like this are found a plenty in event based programming. Which is programming objects based almost entirely on state and behavior. As you can see this has nothing to do with Python vs Java's vs X's implementation of accessors and how using them sucks, or how they aren't Pythonic. Some domains just require this stuff. One of the requirements for designing robust object systems is ensuring the state of objects aren't easily contaminated. That "state" is the objects data (read: stuff the object needs to do something "reliably"). And this is why many overzealous OO languages do "force" you to use accessors. It's not because they hate you or aren't aware of the convenience of having direct access to an object's attributes. It's just because these languages convenience/robustness ratios are different. Thinking in terms of callable vs non-callable is not helpful for me, because it isn't high level enough. Thinking in terms of state and behavior is, because it works regardless of programming language or implementations. This is the reason I like working with Python. I wanted a language that didn't bore me with it semantics and allowed me to focus on design. Let me reiterate, I'm not obsessing over language semantics, I just need practical, not religious, solutions for my problem domain. Bruno Desthuilliers wrote: > mystilleef wrote: > (snip) > > > > Okay, I feel I need to make myself clear. I certainly I'm not blaming > > Python for my mistakes. And I don't think language X is better than > > Python or vice-versa. Okay scrap the vice-versa. It was silly of me to > > name the variable tmp regardless of whatever excuses I have. This also > > doesn't mean in the future I wouldn't use shitty names for my > > attributes. :-) I most likely will. But at least now I know how to > > minimize its impact of such carelessness. I mentioned them above but I > > repeat it hear again. > > > > 1). Make all attributes of a class private/protected . > > Please re-read my answer to your previous mention of this and my other > remarks in this thread (and below in this thread) about the profound > differences between Python and Java wrt/ object model and attribute > access semantics. > > > 2). If a "non-callable" attribute is going to be used outside a class, > > think about making it a property > > Unless you don't need to. > > > and name the property well, > > Indeed !-) > > > Other than that we are just arguing semantics of language. For example, > > your view of objects is by categorizing its attributes in callable and > > non-callable. > > And also API/implementation. These are to orthogonal problems - even in > Java FWIW !-) > > > However, my categorization is state(data) and > > behavior(methods). > > If properties are an equivalent of getters/setters, are properties state > or behaviour ? According to your views, they are behaviour, if I > understood you. In that case, what's the difference between 'directely' > (which in fact implies going thru __getattribute__) accessing a public > "data" attribute and accessing an implementation attribute by the mean > of a descriptor (property or custom) ? > > * before: > > # mylib.py > class Knight(object): > def __init__(self, name): > self.name = name > > def sayHello(self): > print "hello, I'm %s" % self.name > > # mymain.py > from mylib import Knight > k = Knight("Robin") > print k.name > k.sayHello() > k.name = "Lancelot" > k.sayHello() > > * after > # mylib.py > class Knight(object): > def __init__(self, name): > self.name = name > > @apply > def name(): > def fget(self): > return self._xxx.capitalize() > > def fset(self, name): > self._xxx = name > > def sayHello(self): > print "hello, I'm %s" % self.name > > # mymain.py > from mylib import Knight > k = Knight("Robin") > print k.name > k.sayHello() > k.name = "Lancelot" > k.sayHello() > > > > > Neither ways of thinking about it is wrong. > > From the client code (including other methods of the same class) POV, is > Knight.name behaviour or state ? Please, don't see it as a flame or a > pissing context or whatever, and try to seriously answer this question. > > Thinking in terms of state and behaviour is certainly not wrong in > itself, but what is state and what is behaviour ? If I pass a callable > as an argument to another callable, is the first one data or behaviour ? > If I return a callable from a another callable, is the first callable > data or behaviour ? In a Partial application object [1], is the stored > callable data or behaviour ? Is the class of an object data or > behaviour? Is it's metaclass data or behaviour ? > > [1] http://www.python.org/dev/peps/pep-0309/ > > > > It just > > reflects the way we design classes. When I'm coding I certainly don't > > care about how Python accesses tmp. > > Neither do I. But I have in mind how I can change the way it is accessed. > > > What I do care about is how to > > change tmp without breaking code left, right and center and the > > facilities Python provides for making my code robust. > > cf Simon's answer and mines. But your original problem is not related to > tmp being callable or not, it's related to how you use to think about > them, hence name them. > > > Most other OO > > languages provide accessors in addition to keywords for that kind of > > stuff. > > Most OO languages *don't* provide you accessors - they indeed *forces > you* to write them even for the most trivial cases. What Python (or any > other language supporting "computed attributes" syntax) gives you is a > way to avoid writing tedious, boilerplate code. Not more, not less. > > > I knew it wasn't Pythonic, but I wanted to know the Pythonic way > > to do it. So I asked. My query does not automatically suggest Python > > sucks. Neither those it suggest that Java or other OO languages are > > better. I asked because I sincerely wanted to know the Pythonic way > > handling issues like that. > > Mark as implementation what is obviously implementation (be it callable > or not), mark as API what is obviously API (be it callable or not). In > both cases, there will be simple ways to either expose an implementation > name or make a non-callable attribute a property. And *always* try to be > careful about naming, at least (but not restricted to) wrt/ your API. > > > > -- > bruno desthuilliers > python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for > p in '[EMAIL PROTECTED]'.split('@')])" -- http://mail.python.org/mailman/listinfo/python-list