[Tutor] Properties of an object

Andre Engels andreengels at gmail.com
Thu Jan 29 22:27:07 CET 2009


On Thu, Jan 29, 2009 at 7:59 PM, Vicent <vginer at gmail.com> wrote:
> 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.

Yes, you can do it wherever you like. Even outside the class code
(although it makes your code resemble a board of badly boiled
spaghetti). However, the __init__ method is in most cases the 'best'
place to do it - that ensures that every member of the class has their
properties set. If you do it in another method, or outside the class,
you have problems in ensuring that the property is not used before it
comes into existence.

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

The definition says tat the property gets the value for all members of
the class. I have only seen it done this way when it is not changed
later, except in the definition of subclasses.

The prefix "_" means that the property is supposed to be private, that
is, it should not be accessed from outside the class. This may be
because it doesn't really have any meaning for te outside, or because
you want to keep the option of defining your class differently, having
the property get a somewhat different meaning or even be completely
removed. However, Python is very flexible at this point. Many
languages allow you to declare a variable to be 'private', which means
it is not visible at all from the outside. Python uses the "consenting
adults" philosophy here - if, despite the starting _ you still try to
access the variable from the outside, Python assumes that you know
what you are doing, and will let you do it without any objection. In
fact, the _ is not even an official part of the language; rather, it
is more a coding style that many Python programmers use.

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

The amount of extra memory is negligible, and also counteracted by a
(just as negligible) gain in speed. However, your method has a
disadvantage in making it harder to keep the code correct if you
extend it.

Suppose in the future you want to make it so that after the object has
been created, its list can be changed. In your method, there are 4
properties that you have to keep an eye on rather than 2, increasing
the chance of errors. Also, if you always write a.getList() and
a.getListFirstPart() rather than a.list and a.listFirstPart, you or
someone else writing your code will be much less tempted to try to
change it through "a.list = foobar" or "a.listFirstPart = foobar"
(which will cause a 'wrong' state), rather than through
"a.setList(foobar)" or "a.setListFirstPart(foobar)", the effect of
which is completely under your control. Because of this, I prefer to
do _everything_ through methods rather than outside usage of
variables.


-- 
André Engels, andreengels at gmail.com


More information about the Tutor mailing list