Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Instance attributes vs method arguments

1 view
Skip to first unread message

John O'Hagan

unread,
Nov 25, 2008, 2:27:41 AM11/25/08
to pytho...@python.org

Is it better to do this:

class Class_a():
def __init__(self, args):
self.a = args.a
self.b = args.b
self.c = args.c
self.d = args.d
def method_ab(self):
return self.a + self.b
def method_cd(self):
return self.c + self.d

or this:

class Class_b():
def method_ab(self, args):
a = args.a
b = args.b
return a + b
def method_cd(self, args)
c = args.c
d = args.d
return c + d

?

Assuming we don't need access to the args from outside the class,
is there anything to be gained (or lost) by not initialising attributes that
won't be used unless particular methods are called?

Thanks,

John O'Hagan

Marc 'BlackJack' Rintsch

unread,
Nov 25, 2008, 3:30:15 AM11/25/08
to

The question is if `args.a`, `args.b`, …, are semantically part of the
state of the objects or not. Hard to tell in general.

I know it's a made up example but in the second class I'd ask myself if
those methods are really methods, because they don't use `self` so they
could be as well be functions or at least `staticmethod`\s.

Ciao,
Marc 'BlackJack' Rintsch

bief...@gmail.com

unread,
Nov 25, 2008, 3:32:09 AM11/25/08
to

If 'args' is an object of some class which has the attribute a,b,c,d,
why don't you just add
method_ab and method_cd to the same class, either directly or by
sibclassing it?

If for some reason you can't do the above, just make two functions:

def function_ab(args): return args.a + args.b
def function_cd(args): return args.c + args.d

One good thing of Python is that you don't have to make classes if you
don't need to ...

Ciao
------
FB

M.-A. Lemburg

unread,
Nov 25, 2008, 4:21:18 AM11/25/08
to John O'Hagan, pytho...@python.org
On 2008-11-25 08:27, John O'Hagan wrote:
>
> Is it better to do this:
>
> class Class_a():
> def __init__(self, args):
> self.a = args.a
> self.b = args.b
> self.c = args.c
> self.d = args.d
> def method_ab(self):
> return self.a + self.b
> def method_cd(self):
> return self.c + self.d
>
> or this:
>
> class Class_b():
> def method_ab(self, args):
> a = args.a
> b = args.b
> return a + b
> def method_cd(self, args)
> c = args.c
> d = args.d
> return c + d
>
> ?

That depends entirely on what you intend to do with objects
of Class_a and Class_b. In the first case, you are persisting
the argument attributes in the object, in the second case,
you are merely working on them - just like you would in a
function.

> Assuming we don't need access to the args from outside the class,
> is there anything to be gained (or lost) by not initialising attributes that
> won't be used unless particular methods are called?

It is always good practice to provide default values for
instance variables in the class definition, both to enhance
readability and to allow adding documentation regarding
the variables, e.g.

class Class_a:

# Foo bar
a = None

# Foo baz
b = None

...

--
Marc-Andre Lemburg
eGenix.com

Professional Python Services directly from the Source (#1, Nov 25 2008)
>>> Python/Zope Consulting and Support ... http://www.egenix.com/
>>> mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/
>>> mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
________________________________________________________________________
2008-11-12: Released mxODBC.Connect 0.9.3 http://python.egenix.com/

:::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,MacOSX for free ! ::::


eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48
D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
Registered at Amtsgericht Duesseldorf: HRB 46611

Rafe

unread,
Nov 25, 2008, 5:24:57 AM11/25/08
to
snip

> It is always good practice to provide default values for
> instance variables in the class definition, both to enhance
> readability and to allow adding documentation regarding
> the variables, e.g.
>
> class Class_a:
>
>    # Foo bar
>    a = None
>
>    # Foo baz
>    b = None
snip

Those are not instance 'variables' (attributes), they are class
attributes. I used to do that in JScript, so I did it in python when I
moved over. It caused a lot of trouble for me as a beginner. I was
eventually given the advice to stop it. I haven't looked back since
(until now). I think you would just be adding a new self.a which
blocks access to your class.a, but I'm still shaky on this knowledge.

Instance attribute defaults would be inside __init__() and before
unpacking the *args.

- Rafe

John O'Hagan

unread,
Nov 25, 2008, 5:48:01 AM11/25/08
to pytho...@python.org

Would you mind elaborating a little on that first sentence?


>
> I know it's a made up example but in the second class I'd ask myself if
> those methods are really methods, because they don't use `self` so they
> could be as well be functions or at least `staticmethod`\s.

I guess I went overboard keeping the example simple :) : the real case has
many methods, and they all use "self" (except one, actually, so I'm looking
up "static methods" now; thanks).


Regards,

John


Marc 'BlackJack' Rintsch

unread,
Nov 25, 2008, 6:04:29 AM11/25/08
to
On Tue, 25 Nov 2008 10:48:01 +0000, John O'Hagan wrote:

> On Tue, 25 Nov 2008, Marc 'BlackJack' Rintsch wrote:
>> On Tue, 25 Nov 2008 07:27:41 +0000, John O'Hagan wrote:
>> > Is it better to do this:
>> >
>> > class Class_a():
>> > def __init__(self, args):
>> > self.a = args.a
>> > self.b = args.b
>> > self.c = args.c
>> > self.d = args.d
>> > def method_ab(self):
>> > return self.a + self.b
>> > def method_cd(self):
>> > return self.c + self.d

>> > […]


>>
>> The question is if `args.a`, `args.b`, …, are semantically part of the
>> state of the objects or not. Hard to tell in general.
>
> Would you mind elaborating a little on that first sentence?

Do `self.a`, `self.b`, …, define the state of a `Class_a` instance or
not? One can't answer that question without knowing the meaning of the
class and the attributes.

Ciao,
Marc 'BlackJack' Rintsch

Rafe

unread,
Nov 25, 2008, 6:04:50 AM11/25/08
to

I'm not sure if you are asking a technical question or a design
question. If it helps, I try to think of an object as a thing which
has a job to do. If the 'thing' needs information every time to define
what it is, or give it a starting state, then that is an argument of
__init__() . If I want the object to change or handle something which
is a logical task of 'thing', then I give it what it needs via
properties or methods (I find I almost never use "public" instance
attributes, but then again I am usually writing SDKs which is all
about interface).

Not sure if that helps...

- Rafe

Bruno Desthuilliers

unread,
Nov 25, 2008, 10:45:12 AM11/25/08
to
M.-A. Lemburg a écrit :
(snip)

> It is always good practice to provide default values for
> instance variables in the class definition, both to enhance
> readability and to allow adding documentation regarding
> the variables, e.g.

Your opinion. As far as I'm concerned, using class variables this way is
more of a WTF than a "good practice".

John O'Hagan

unread,
Nov 25, 2008, 8:49:37 PM11/25/08
to pytho...@python.org
You've picked up my fundamental confusion! Thanks to your reply and others I
think that's cleared up for me now, which just leaves the technical
question: insofar as one is only interested in accessing methods, is there an
difference in efficiency (for large enough number of methods and arguments)
between

a) passing all arguments to __init__() and accessing them via self within
individual methods:

class = Class(all_class_args)
class.method_a()
class.method_b()
...
or

b) passing the arguments needed by each method when it is called on an
instance:

class = Class()
class.method_a(a_args)
class.method_b(b_args)
...

Thanks to all,

John


George Sakkis

unread,
Nov 25, 2008, 9:34:54 PM11/25/08
to
On Nov 25, 8:49 pm, John O'Hagan <m...@johnohagan.com> wrote:

> is there an
> difference in efficiency (for large enough number of methods and arguments)
> between
>
> a) passing all arguments to __init__() and accessing them via self within
> individual methods:
>
> class = Class(all_class_args)
> class.method_a()
> class.method_b()
> ...
> or
>
> b) passing the arguments needed by each method when it is called on an
> instance:
>
> class = Class()
> class.method_a(a_args)
> class.method_b(b_args)
> ...

The difference in API here is more crucial than the difference in
performance. Deciding between the two based on the (guessed or
measured) performance improvement misses the point of OO design.

George

Ben Finney

unread,
Nov 25, 2008, 10:05:08 PM11/25/08
to
John O'Hagan <ma...@johnohagan.com> writes:

> insofar as one is only interested in accessing methods, is there an
> difference in efficiency (for large enough number of methods and
> arguments) between
>
> a) passing all arguments to __init__() and accessing them via self
> within individual methods:
>
> class = Class(all_class_args)
> class.method_a()
> class.method_b()
> ...
> or
>
> b) passing the arguments needed by each method when it is called on
> an instance:
>
> class = Class()
> class.method_a(a_args)
> class.method_b(b_args)
> ...

Note that you've chosen confusing names for the above. When you call
the class, the return value will be an *instance of* the class, so
binding the name ‘class’ to that return value has two problems: it's a
misnomer, and it's a syntax error because ‘class’ is a reserved word.

As for your actual question: Write code that's clear in intent, and
worry about efficiency only when you *measure* a performance problem.

--
\ “First they came for the verbs, and I said nothing, for verbing |
`\ weirds language. Then, they arrival for the nouns and I speech |
_o__) nothing, for I no verbs.” —Peter Ellis |
Ben Finney

Steven D'Aprano

unread,
Nov 25, 2008, 10:07:41 PM11/25/08
to
On Tue, 25 Nov 2008 10:21:18 +0100, M.-A. Lemburg wrote:

> It is always good practice to provide default values for instance
> variables in the class definition, both to enhance readability and to
> allow adding documentation regarding the variables, e.g.
>
> class Class_a:
>
> # Foo bar
> a = None
>
> # Foo baz
> b = None

"Always"?


I would question that. If the instance attribute is always set, then the
class attribute is just noise. It's not *wrong* exactly, but it is
redundant. The documentation point is worthwhile, but I would say it is
in the wrong place: it should be documented in the class docstring, not
the source code.


--
Steven

John O'Hagan

unread,
Nov 25, 2008, 10:45:26 PM11/25/08
to pytho...@python.org
On Wed, 26 Nov 2008, Ben Finney wrote:
> John O'Hagan <ma...@johnohagan.com> writes:
> > insofar as one is only interested in accessing methods, is there an
> > difference in efficiency (for large enough number of methods and
> > arguments) between
> >
> > a) passing all arguments to __init__() and accessing them via self
> > within individual methods:
> >
> > class = Class(all_class_args)
> > class.method_a()
> > class.method_b()
> > ...
> > or
> >
> > b) passing the arguments needed by each method when it is called on
> > an instance:
> >
> > class = Class()
> > class.method_a(a_args)
> > class.method_b(b_args)
> > ...
>
> Note that you've chosen confusing names for the above. When you call
> the class, the return value will be an *instance of* the class, so
> binding the name ‘class’ to that return value has two problems: it's a
> misnomer, and it's a syntax error because ‘class’ is a reserved word.

I know, sorry, just a simplified example...s/class/class_instance/.

John


Aahz

unread,
Nov 26, 2008, 2:23:47 PM11/26/08
to
In article <mailman.4506.1227604...@python.org>,

M.-A. Lemburg <m...@egenix.com> wrote:
>
>It is always good practice to provide default values for instance
>variables in the class definition, both to enhance readability and to
>allow adding documentation regarding the variables, e.g.

Actually, my company uses an occasional pattern of detecting whether an
attribute has ever been set with hasattr(). I am not particularly fond
of that mechanism because it has been the occasional source of subtle
bugs, but I also see the utility.
--
Aahz (aa...@pythoncraft.com) <*> http://www.pythoncraft.com/

"It is easier to optimize correct code than to correct optimized code."
--Bill Harlan

0 new messages