Instance attributes vs method arguments

Discussion in 'Python' started by John O'Hagan, Nov 25, 2008.

  1. John O'Hagan

    John O'Hagan Guest

    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
     
    John O'Hagan, Nov 25, 2008
    #1
    1. Advertising

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


    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
     
    Marc 'BlackJack' Rintsch, Nov 25, 2008
    #2
    1. Advertising

  3. John O'Hagan

    Guest

    On 25 Nov, 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
    >
    > ?
    >
    > 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


    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
     
    , Nov 25, 2008
    #3
  4. John O'Hagan

    John O'Hagan Guest

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

    >
    > 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?
    >
    > 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
     
    John O'Hagan, Nov 25, 2008
    #4
  5. 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
     
    Marc 'BlackJack' Rintsch, Nov 25, 2008
    #5
  6. John O'Hagan

    Rafe Guest

    On Nov 25, 5:48 pm, 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

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

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


    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
     
    Rafe, Nov 25, 2008
    #6
  7. John O'Hagan

    John O'Hagan Guest

    On Tue, 25 Nov 2008, Rafe wrote:
    > On Nov 25, 5:48 pm, 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
    > > > >
    > > > > 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?
    > > >
    > > > 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?
    > >
    > > > 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

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

    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
     
    John O'Hagan, Nov 26, 2008
    #7
  8. On Nov 25, 8:49 pm, John O'Hagan <> 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
     
    George Sakkis, Nov 26, 2008
    #8
  9. John O'Hagan

    John O'Hagan Guest

    On Wed, 26 Nov 2008, Ben Finney wrote:
    > John O'Hagan <> 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
     
    John O'Hagan, Nov 26, 2008
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Gerard Flanagan
    Replies:
    3
    Views:
    494
    Terry Hancock
    Nov 19, 2005
  2. M.-A. Lemburg
    Replies:
    4
    Views:
    545
  3. Raj Singh
    Replies:
    2
    Views:
    217
    Rick DeNatale
    May 29, 2008
  4. Greg Hauptmann
    Replies:
    9
    Views:
    268
    Loren Segal
    Jun 16, 2008
  5. Jayden
    Replies:
    16
    Views:
    561
    Steven D'Aprano
    Sep 29, 2012
Loading...

Share This Page