getting the state of an object

Discussion in 'Python' started by Franck Ditter, Oct 7, 2012.

  1. Hi !

    Another question. When writing a class, I have often to
    destructure the state of an object as in :

    def foo(self) :
    (a,b,c,d) = (self.a,self.b,self.c,self.d)
    ... big code with a,b,c,d ...

    So I use the following method :

    def state(self) :
    return (self.a,self.b,self.c,self.d)

    so as to write :

    def foo(self) :
    (a,b,c,d) = self.state()
    ... big code with a,b,c,d ...

    This is probably not the best Python way to code, is it ?
    Is there a simple way to get the *ordered* list of instance
    variables as given in the parameter list of __init__ ?
    __dict__ gives it but not in order...
    Thanks a lot,

    franck
     
    Franck Ditter, Oct 7, 2012
    #1
    1. Advertising

  2. On Sun, Oct 7, 2012 at 7:50 PM, Franck Ditter <> wrote:
    > def foo(self) :
    > (a,b,c,d) = (self.a,self.b,self.c,self.d)
    > ... big code with a,b,c,d ...
    >


    This strikes me as ripe for bug introduction. There's no problem if
    you're just reading those values, and mutating them is equally fine,
    but suddenly you need a different syntax for modifying instance
    members.

    def foo(self) :
    (a,b,c,d) = (self.a,self.b,self.c,self.d)
    e = a+b
    c.append(1234)
    d=self.d = 57 # Oops, mustn't forget to assign both!


    Since Python lacks the extensive scoping rules of (say) C++, it's much
    simpler and safer to be explicit about scope by adorning your instance
    variable references with their "self." tags. There's a guarantee that
    you can use "self.a" in any situation where you want to manipulate
    that member, a guarantee that's not upheld by the local "a".

    In theory, I suppose you could use a C-style preprocessor to help you.

    class Foo(object):
    #define asdf self.asdf
    #define qwer self.qwer

    def __init__(self,a,q):
    asdf=a; qwer=q

    def __repr__(self):
    return "Foo(%s,%s)"%(asdf,qwer)

    This is not, however, Pythonic code. But if you made some kind of
    better declaration than #define, and used a preprocessor that
    understood Python indentation rules and flushed its token list at the
    end of the class definition, you could perhaps make this look
    not-ugly. I still wouldn't recommend it, though.

    ChrisA
     
    Chris Angelico, Oct 7, 2012
    #2
    1. Advertising

  3. On Sun, 07 Oct 2012 10:50:38 +0200, Franck Ditter wrote:

    > Hi !
    >
    > Another question. When writing a class, I have often to destructure the
    > state of an object as in :
    >
    > def foo(self) :
    > (a,b,c,d) = (self.a,self.b,self.c,self.d)
    > ... big code with a,b,c,d ...


    There's your problem right there: "big code". Methods should be small,
    ideally no more than a dozen lines or so. In my experience, small methods
    that have a very tight focus on doing one thing make it much easier to
    write, debug and maintain the method, and as a bonus having to write
    "self.a" is less of a burden.

    I've just looked at one of my classes, picked randomly, and the largest
    method is twelve lines, the second largest is eight, and the average is
    three lines.


    > So I use the following method :
    >
    > def state(self) :
    > return (self.a,self.b,self.c,self.d)
    >
    > so as to write :
    >
    > def foo(self) :
    > (a,b,c,d) = self.state()
    > ... big code with a,b,c,d ...
    >
    > This is probably not the best Python way to code, is it ?


    Not really the best. But I've seen worse.

    If you *have* to write "big code with a,b,c,d" then this is probably
    acceptable. But better to refactor your big method into smaller methods
    that don't need to use self.a, self.b, self.c, self.d so many times that
    writing them explicitly is a nuisance.

    > Is there a
    > simple way to get the *ordered* list of instance variables as given in
    > the parameter list of __init__ ?


    What you have written in method "state" is the simple way.

    By the way, we prefer "instance attribute" or even "instance member" over
    "instance variable" here.



    --
    Steven
     
    Steven D'Aprano, Oct 7, 2012
    #3
  4. Franck Ditter

    Miki Tebeka Guest

    > Is there a simple way to get the *ordered* list of instance
    Here's one way to do it (weather doing it is a good idea or not is debatable):

    from operator import attrgetter

    def __init__(self, a, b, c, d):
    self.a, self.b, self.c, self.d = a, b, c, d
    get = attrgetter('a', 'b', 'c', 'd')
    self.state = lambda: get(self)
     
    Miki Tebeka, Oct 7, 2012
    #4
  5. Franck Ditter

    Roy Smith Guest

    In article <507170e9$0$29978$c3e8da3$>,
    Steven D'Aprano <> wrote:

    > I've just looked at one of my classes, picked randomly, and the largest
    > method is twelve lines, the second largest is eight, and the average is
    > three lines.


    I took a look at a subtree of the project I'm working on now. 116
    python files, 20 kloc, 330 functions (mostly class methods). I did a
    quick-and-dirty "grep -n" job on them to find the line numbers of the
    def statements, then another quick-and-dirty python script to find the
    differences, and summarize. Results below (second column is length of
    'def' block in lines, first column is number of blocks of that length).

    This is just dumb line counting; no attempt to exclude block comments,
    white space, docstrings, etc.

    There's three different authors represented here, but I'd guess 70% of
    the code is mine. Of the three, I'm probably the one who writes the
    most refactored code (i.e. smallest functions).

    I just went and found the longest of these (193 lines). It starts with
    a 95 line block comment. Of the 100-or so lines of real code, I suppose
    with some effort it could have been refactored some, but not hugely.


    7 3
    19 4
    12 5
    17 6
    10 7
    16 8
    10 9
    6 10
    8 11
    11 12
    4 13
    8 14
    9 15
    13 16
    4 17
    8 18
    9 19
    5 20
    9 21
    3 22
    6 23
    5 24
    4 25
    4 26
    4 27
    3 28
    2 29
    1 30
    3 31
    4 32
    4 33
    8 34
    2 35
    2 36
    3 37
    2 39
    1 40
    3 41
    1 42
    3 43
    2 44
    2 45
    1 46
    2 47
    1 48
    1 51
    2 54
    1 55
    2 56
    2 59
    1 60
    1 62
    1 63
    1 64
    1 65
    1 74
    1 75
    1 78
    1 94
    1 100
    1 105
    1 148
    1 164
    1 193
     
    Roy Smith, Oct 7, 2012
    #5
    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. David Lamb
    Replies:
    1
    Views:
    695
  2. Weng Tianxiang
    Replies:
    7
    Views:
    1,132
    Mike Treseler
    Nov 25, 2003
  3. shamanthakamani
    Replies:
    1
    Views:
    3,523
    Natty Gur
    Nov 20, 2003
  4. Not Liking Dot Net Today
    Replies:
    0
    Views:
    642
    Not Liking Dot Net Today
    Apr 21, 2004
  5. =?Utf-8?B?Sm9zaHVhIFdlaXI=?=

    getting the application state object.

    =?Utf-8?B?Sm9zaHVhIFdlaXI=?=, Oct 9, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    424
    Hermit Dave
    Oct 9, 2004
Loading...

Share This Page