Le Thu, 29 Jan 2009 19:59:09 +0100, Vicent <vgi...@gmail.com> a écrit :
> This is an easy question, I guess, but I am not able to find out the answer. > > In fact, it is both a Python question and a general programming "style" > question. > > I want to define a class that contains a list (or a NumPy array) of elements > of a certain type, and an integer: > > class ExampleList : > def __init__(self, list, position) : > self.list = list > self.position = position > > > This is clear to me. > > My first question, which is Python related: > > (1) Where are the right places to define PROPERTIES for my class, and how (I > mean, which is the right syntax) must I define them? > > As far as I know, the usual place where properties are "declared" and > assigned is in the __init__ function. > > Can I define properties in other parts of the "Class" code? I am not able to > deduce it from the things I've read. > > I've also seen sometimes something like this: > > > class ExampleFoo : > _property1 = 0 > > [...] > > And I think that later I found "self._property1" or "self.property1", but I > am not sure of that. Anyway, why the prefix "_", and what does that > definition "_property = 0" mean and imply? Rather pleased to read such a question here, because when I speak like that the reactions let me feel like if I were a martian ;-} [I think I get why you are trouble, why the "python way" seems strange, so I will try to answer. But my words are to be read strictly as a personal view. They probably do not reflect the views of the majority.] There is no real native support for ordinary OOP in python, meaning as is done in most other languages, or according to the theory. There is instead a POOP, where the first P stands for 'python'. The python way lacks for constraints which are considered basic things elsewhere, such as defining a strict list of properties. You wont find e.g.: class MyCLass # list of visible properties ... # list of private things ... On the contrary, python is much more flexible. It lets you bind anything to an object, at anytime and from anywhere (inside/outside): obj = MyClass("prop1") obj.quality = "prop2" obj.method() # list obj's bound attributes, # stored in "magic" attr '__dict__' for attr in obj.__dict__.items(): print attr ==> I'm doing something. I got a result. ('quality', 'prop2') ('result', 'present result') ('start_prop', 'prop1') This way has huge advantages. It lets doing many things in a light, easy and straighforward manner, compared to many languages where simple things rapidly get heavy. On the other hand, there is a 'heavy' ;-) lack of structure, of frame, of standard, that easily lets code get chaotic -- especially because anything can be influenced by anything else "in the background". Good practice, clear code, sensible structure only depend on the developper's discipline. There are also (more & more) special features (somewhat abstract and complicated for my taste), that allow a programmer forcing constraints and structure. But they hardly fit the python way. It's forced, indeed. For instance, there are several ways to forbid adding or changing properties -- so that the client willget an error (that may let the old pythonist stuck). > Coming back to my ExampleList, I have another "philosophic" question. > > Suppose I'm interested (many times within my "main" program) to recover a > part of the list contained by an ExampleList object. To be more clear: > > >>> a = ExampleList([1,2,3,4], 2) > >>> a.list > [1, 2, 3, 4] > >>> a.position > 2 > > I want to get the second part of the list, I mean, the part of list > a.list that goes from position a.position until the last element in > the list. > > I know I can do it like this: > > >>> a.list[a.position:] > [3, 4] > > Or, if I want the first part of the list: > > >>> a.list[:a.position] > [1, 2] > > > My problem/question/dilemma: I want to define it as a property or as a > method in the class definition, because I am going to need many times "the > first part of te list" or "the second part of the list". > > For me, I see it as a property of the object, I mean: "tell me which is your > first part". It is not like an action over the object or to/from/related to > the object (that would be a method, then). > > So, this kind of "derived" properties (because they are based on two other > previously defined "primary" properties) are better to be defined as > methods, or it is the same? > > I mean, what I would like to do is this: > > class ExampleList : > def __init__(self, list, position) : > self.list = list > self.position = position > self.list_1stpart = self.list[:self.position] > self.list_2ndpart = self.list[self.position:] > > > Is that right? Is that good practice? If I want to define > self.list_1stpart as a property, is the __init__ function the only and > the best place to do it? > > If not, I suppose I'll have to define it as a method, and then it will look > like something like this: > > [... within the class definition ...] > > def list_1stpart(self) : > return self.list[:self.position] > > > Then I'll call the method like this: > > >>> a.list_1stpart() > [1, 2] > > For me, the "()" look like artificial, not necessary. I would prefer just to > type "a.list_1stpart" , a property. > > The general case is (the second question): > > (2) properties which can be derived from other "primary" properties, are > they just methods?? > > I don't know which approach is more correct, from any point of view... By > the way, does the "property" approach consume much memory or space than the > "method" approach?? > > Thank you very much for your patience... > > This is not directly related to python, as you said -- if I well understand what you mean. For any property, you always have the choice between giving the client direct access to the data, or writing a method that returns it. It may be a question of style. When a property is dependant on others, such as a sum of 2 values, or the 2 parts of your list, then the choice becomes: -1- Either, compute the prop each time the other values change, then let the result available as a simple data attribute. -2- Or write a function that computes & returns the result on demand only. Well, my opinion is: if the base data change much, and the result is not often required, choose -2- If the source data change few, and the result is often required, choose -1-. If you want -1-, then you simply transfer the charge to the base properties -- or rather to methods the client will have to use for setting the properties: def set_list(new_list): self.list = new_list # compute parts 1 & 2 def set_pos(new_pos): self.pos = new_pos # compute parts 1 & 2 Denis ------ la vida e estranya _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor