FAQ
Hi all,
from the subject of my post, you can see I do not
like very much OOP... and I am not the only one...
Knowing that python is intrinsecally OO, I propose
to move all OOP stuff (classes, instances and so on)
to modules.
In this way the OOP fan can keep on using it, but
in a module recalled by import in the user script.
The advantage is that the user can call function and
methods by a well-known sintax. Not to mention the
sharp increase in re-usability of code...
Bye.

Search Discussions

  • Andrea Crotti at Apr 10, 2011 at 10:57 am

    newpyth <newpyth at gmail.com> writes:

    Hi all,
    from the subject of my post, you can see I do not
    like very much OOP... and I am not the only one...
    Knowing that python is intrinsecally OO, I propose
    to move all OOP stuff (classes, instances and so on)
    to modules.
    In this way the OOP fan can keep on using it, but
    in a module recalled by import in the user script.
    The advantage is that the user can call function and
    methods by a well-known sintax. Not to mention the
    sharp increase in re-usability of code...
    Bye.
    OOP makes like easier also to the user, if you don't like it write your
    own non-OOP wrappers around the OOP functions ;)

    But I think that you should probably use another language if you don't
    like OOP so much...
  • Steven D'Aprano at Apr 10, 2011 at 1:33 pm

    On Sun, 10 Apr 2011 03:35:48 -0700, newpyth wrote:

    Hi all,
    from the subject of my post, you can see I do not like very much OOP...
    and I am not the only one... Knowing that python is intrinsecally OO, I
    propose to move all OOP stuff (classes, instances and so on) to modules.
    Python is based on objects, but it is not an object-oriented language. It
    is a multi-paradigm language: it includes elements of OOP, functional,
    procedural and imperative programming. Some of these are fundamental to
    Python: the "import" statement is pure imperative style.

    For example, Python has:

    import module # imperative style
    len(mylist) # procedural
    map(func, sequence) # functional
    mylist.sort() # object-oriented


    With a third-party package, Pyke, you can use Prolog-style logic
    programming:

    http://pyke.sourceforge.net/

    (albeit with a procedural syntax). There are probably third-party
    packages for agent-based programming as well.

    If you don't like OOP, you can write your code using a functional style,
    or a procedural style. List comprehensions and generator expressions are
    *very* common in Python, which come from functional and pipeline styles
    of programming.

    If you really, really hate OOP, you can even write your own wrappers for
    Python objects.

    Unlike Java, Python encourages by example the use of shallow class
    hierarchies. Most Python classes are only two levels deep:

    object
    +-- list
    +-- tuple
    +-- dict
    +-- set
    etc.

    instead of the deep, complex hierarchies beloved by some OOP languages:

    Object
    +-- Collection
    +-- Sequence
    +-- MutableSequence
    +-- IndexableMutableSequence
    +-- SortableIndexableMutableSequence
    +-- SortableIndexableMutableSequenceArray
    +-- List
    +-- ImmutableSequence
    +-- IndexableImmutableSequence
    +-- SortableIndexableImmutableSequence
    +-- SortableIndexableImmutableSequenceArray
    +-- Tuple
    +-- Mapping
    etc.



    So while everything in Python is an objects, the language itself is only
    partly object oriented, and it rarely gets in the way. The OO aspect of
    Python is mostly syntax and namespaces.



    --
    Steven
  • Newpyth at Apr 10, 2011 at 4:53 pm
    Hi all,
    I must thank before Andrea Crotti and Steven D'Aprano, which kindly
    replayed to my post... they deserve an answer.
    To Andrea Crotti's "OOP makes life easier also to the user"... that is
    NOT
    my experience...
    I'm not pretending that everyone else thinks like me (also if many
    people do...
    load any search engine with "againt OOP" or "criticisms againt OO" to
    verify...)
    I was trying to get caller-callee tree from the module trace (like do
    cflow
    with C sources, together with xref)... I think that UML is a loss of
    time...
    "trace" has three classes whose methods I can't easily arrange in the
    caller-callee tree, mainly because IMHO they are similar to functions
    declared inside another function.
    So I taught to move classes in a module (trace_classes.py) saved
    in the same folder of the python source to be traced.
    Only using "from trace_classes import *" in the trace_noclasses.py
    which contained
    the residual part of trace after removing classes, you had the same
    result as
    the original trace...
    In fact "python trace -t mysource.py" worked the same as:
    "python trace_noclasses.py -t mysource.py" if you of course load the
    classes
    by "from trace_classes import * (as mentioned before)
    To trace the module trace.py you can use:
    python trace.py -t trace.py - t mysource.py (it seems that you must
    include
    at least a source to be traced".)
    The problems arise if you want to use the standard import...with the
    two
    components of trace (w/ or w/o classes)... because of the instances
    or the obiects defined with class template...
    For me its enough to study a module with classes and instances
    defined outside them and can use it without referring to internal
    istances...
    Do you know a module of this kind (trace itself could be the answer
    but the
    source is too complicated for me...)
    I would not like to be compelled to revert to another language as the
    suggestion
    of Andrea Crotti ("I think that you should probably use another
    language if you don't like OOP so much...")
    As far Steven D'Aprano and his "Python is based on objects, but it is
    not an object-oriented language." is concerned, I could agree with him
    (... with some difficulty, however...)
    For him (and I agree) "python is a multi-paradigm language: it
    includes elements of OOP, functional, procedural and imperative
    programming", but the OO example is merily "mylist.sort() # object-
    oriented", without citing the classes and the
    multiple inheritance or other obscure property.
    My main goal is to arrange OO in a paradigmatic manner in order to
    apply to it the
    procedural scheme. especially to the caller or called modules.
    Bye.
  • Andrea Crotti at Apr 10, 2011 at 5:42 pm
    newpyth <newpyth at gmail.com> writes:


    [...]
    My main goal is to arrange OO in a paradigmatic manner in order to
    apply to it the
    procedural scheme. especially to the caller or called modules.
    Bye.
    I have some troubles understanding what you mean.
    Can you write an example of code that it's for you annoying and how
    would you like to write instead?

    About the OO criticism, if they make sense, they don't really apply to
    python, but more to languages like java.

    Python gives you enough freedom to be procedural or functional.
  • Newpyth at Apr 12, 2011 at 3:33 pm
    Hi Andrea,
    excuse my beeing criptic (you wrote: "I have some troubles
    understanding what you mean") but I coudn't to go on too long.
    Now I can conclude my speech...
    When I was younger I transformed a big Clipper program in
    simil-C in order to apply cflow... and I succeeded...
    but Clipper wasn't OO!
    To better explain I must introduce cflow...
    <code>From: http://www.gnu.org/software/cflow/manual/cflow.txt

    /* whoami.c - a simple implementation of whoami utility */
    #include <pwd.h>
    #include <sys/types.h>
    #include <stdio.h>
    #include <stdlib.h>

    int who_am_i (void) #~13
    {
    struct passwd *pw;
    char *user = NULL;

    pw = getpwuid (geteuid ()); #~18
    if (pw)
    user = pw->pw_name;
    else if ((user = getenv ("USER")) == NULL) #~21
    {
    fprintf (stderr, "I don't know!\n"); #~23
    return 1;
    } #~26
    printf ("%s\n", user);
    return 0;
    }

    int main (int argc, char **argv) #~31
    {
    if (argc > 1)
    {
    fprintf (stderr, "usage: whoami\n"); #~35
    return 1;
    }
    return who_am_i (); #~38
    }

    Running `cflow' produces the following output:

    $ cflow whoami.c
    main() <int main (int argc,char **argv) #~:31>:
    ~ all C programs start with main()
    +-- fprintf() ~ called from #~35
    +-- who_am_i() <int who_am_i (void) #~13 ~ #~38
    +-- getpwuid() ~ #~18
    +-- geteuid() ~ #~18
    +-- getenv() ~ #~21
    +-- fprintf() ~ #~23
    +-- printf() ~ #~26
    </code<
    This is a direct call graph showing "caller--callee" dependencies

    Now let us analyse a python script...In this case the presence of
    OO constructs makes much more difficult to obtain a call graph...
    (at least for me!).
    To better show the problems, I take for example a very small script.
    <code>
    # 2instances.py
    # from: http://www.freenetpages.co.uk/hp/alan.gauld/tutclass.htm
    # w/ some adds up

    class C:
    def __init__(self, val):
    self.val = val
    def f(self):
    print "hello, my value is:", self.val

    # create two instances
    a = C(27)
    b = C(42)

    def E(): #~15
    print 'hello '+ F()
    G() #~17

    def F(): #~18
    return raw_input('Addressed to ') #~19

    def G(): #~21
    print 'Hello world'

    # first try sending messages to the instances
    a.f(),'************'
    # hello, my value is 27
    b.f()
    # hello, my value is 42

    # now call the method explicitly via the class
    C.f(a)
    # hello, my value is 27

    # Addressing functions
    E() #~35
    G() #~36

    """ call tree w/o classes and objects:
    E() #~15 called from #~35
    +-- F() #~18 16
    +-- raw_input('Addressed to ') # called from 19
    +-- G() #~21 18

    G() #~21 36
    """
    </code>
    Beeing the script so small, the above call tree can be
    build up by hand, but in every case in am not able to
    incorporate classes, instances and method calls...
    Instead, if I move "all" the OO references to a module
    (for example m2instancesOO.py saved in the same dir as the
    part w/o OO)
    I could fictitiously trasform OOP in "procedural" programming,
    getting therefore only function definitions and calls.
    It not an easy task... therefore I called help.
    in my experience, I am convinced that call trees (together with xref)
    are the main tools to understand not trivial python programs.
    Instead of using debuggers, with these tools (and with the
    judicious use of trace) you can solve any bug and besides that
    acquire a better understanding of the program.
    Another advantage of moving OO stuff to modules is the "sharp
    increase in re-usability of code...
    In my understanding modules are the python's implementation
    of libraries very much used by other languages.
    Bye.
  • Adam Tauno Williams at Apr 12, 2011 at 5:26 pm

    On Tue, 2011-04-12 at 08:33 -0700, newpyth wrote:
    """ call tree w/o classes and objects:
    E() #~15 called from #~35
    +-- F() #~18 16
    +-- raw_input('Addressed to ') # called from 19
    +-- G() #~21 18

    G() #~21 36
    """
    </code>
    Beeing the script so small, the above call tree can be
    build up by hand,
    IMO, in any real-world application your call-graph is miles long. This
    is really not much more than a stack trace.
    It not an easy task... therefore I called help.
    in my experience, I am convinced that call trees (together with xref)
    are the main tools to understand not trivial python programs.
    Instead of using debuggers,
    Even better, since the real world usually involves non-trivial programs,
    is to learn to use debuggers and the provided tools. I've not had any
    issues read the strack-trace generated by an exception in an OO Python
    application [as I maintain a >100,000 line and growing component
    oriented Python applications
    <https://www.ohloh.net/p/coils/analyses/latest>]
    with these tools (and with the
    judicious use of trace) you can solve any bug and besides that
    acquire a better understanding of the program.
    Another advantage of moving OO stuff to modules is the "sharp
    increase in re-usability of code...
    Only if your code remains as trivial as your examples.
    In my understanding modules are the python's implementation
    of libraries very much used by other languages.
    Making these kind of analogies is not helpful and will only confuse. C
    uses libraries, .NET uses assemblies, Python uses modules... and how
    these function and perform differs in important ways.
  • Andrea Crotti at Apr 12, 2011 at 6:49 pm

    newpyth <newpyth at gmail.com> writes:

    Hi Andrea,
    excuse my beeing criptic (you wrote: "I have some troubles
    understanding what you mean") but I coudn't to go on too long.
    Now I can conclude my speech...
    When I was younger I transformed a big Clipper program in
    simil-C in order to apply cflow... and I succeeded...
    but Clipper wasn't OO!
    To better explain I must introduce cflow...
    <code>From: http://www.gnu.org/software/cflow/manual/cflow.txt
    [...]

    Apart from literate programming noone codes trying to write such a
    linear work flow, for many good reasons.

    You should find the right metaphor to solve your problem and code it,
    then you can analyze the real call graph with the right tools, like for
    example

    http://pycallgraph.slowchop.com/

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedApr 10, '11 at 10:35a
activeApr 12, '11 at 6:49p
posts8
users4
websitepython.org

People

Translate

site design / logo © 2022 Grokbase