Thoughts about Python

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Marco Aschwanden

    Thoughts about Python

    Hi

    I don't have to talk about the beauty of Python and its clear and
    readable syntax... but there are a few things that striked me while
    learning Python.

    I have collected those thoughts. I am sure there are many discussions
    on the "problems" mentioned here. But I had this thoughts without
    looking into any forums or anything... it is kind of feedback.

    Thanks for this marvellous language,
    Marco



    *** Problem: clumsy static class methods

    In order to create a static method we have to use a the builtin
    staticmethod(fu nction):

    class C (object):
    def f(arg1, arg2, ...): ...
    f = staticmethod(f)

    Why? The speciality of a "static" method is: It has no access to any
    instance vars. The following class is easier to read and understand
    what a static method is about... as a positive side-effect: self is
    not available and it can't be used!

    class c (object):
    def staticMethod(ar g1, arg2, ...):
    # self is not handed in... hence I can't use the instance vars
    pass
    def normalMethod(se lf, arg1, arg2, ...):
    pass

    There is no need for the builtin... as I understand it: the builtin is
    a workaround...



    *** Problem: clumsy properties for classes

    property( [fget[, fset[, fdel[, doc]]]])

    class C(object):
    def getx(self): return self.__x
    def setx(self, value): self.__x = value
    def delx(self): del self.__x
    x = property(getx, setx, delx, "I'm the 'x' property.")


    I don't like this one either. It is not necessary because it describes
    something that should be clear by looking at the class/code. A
    convention would make the syntax clearer and more intuitive and by
    looking at the definition of a method you would know: This is a
    getter, setter or deleter. My proposal:

    all getters start with __get__
    all setters start with __set__
    all deleters start with __del__

    If someone uses:

    prop.x = 5

    Python checks whether the var 'x' exists on prop. If it does - it is
    set. If it doesn't exist Python checks for '__set__x' if it doesn't
    exist either... a AttributeError is raised:


    class PropertyExample (object):
    """A demonstration class for the property idea.

    This class is used afterwards as follows:
    prop = PropertyExample ()
    prop.x = 5 # __set__x(self, 5) is called behind the scenes
    print prop.x # __get__x(self) is called behind the scenes
    del prop.x # __del__x(self) is called behind the scenes"""

    def __init__(self):
    self.__x = None

    def __del__x(self):
    del self.__x
    def __get__x(self):
    return self.__x
    def __set__x(self, value):
    self.__x = value



    *** Problem: Many builtins are not necessary

    Many builtins are not necessary. To name a few: min / max / len

    This functions should be defined on the class:

    ["I", "like", "Python"].len()
    "I".len()
    {1:"I", "2":"like", 3:"Python"}.len ()
    (1,2,3,4).len()

    "Throwing away" this builtins would flatten the alreay flat learning
    curve once more (you don't have to learn that many builtins) ... these
    functions belong to the class and they are naturally expected there.
    One weakness of a language as (Visual)Basic, PHP, ... is its payload
    of available functions... Python's OO helps here to diminish the need
    for lots of functions.


    *** Problem: tuples are not necessary

    Throw them away in the long run - for now make them depracted. It is
    hard to argue in favour of tuples. There might to 2 reason:

    1. It is MUCH faster than a list
    2. We can't live without an immutable list

    Cons:

    1. I don't think that tuples deliver a big performance gain.
    2. Python makes so many "soft" conventions (eg.: don't use
    vars/methods with 2 leading underscores) but when it comes to tuples
    the immutable issue is very important... why? I hope the tuples will
    disappear in P3K.


    *** Problem: builtins list() dict() ...

    A list, a dictionary, a str, an int, a float are builtin functions...

    myList = list()
    myDict = dict()
    myString = str(45)

    The list-function instantiates a new list... it is actually nothing
    but an overloaded List class. Why are the handed in as functions? In a
    OO environment it should be more the instatiation of a class rather
    than a function and classes start with an uppercase letter:

    myList = List()
    myDict = Dict()
    myString = String(45)
  • Michael Hudson

    #2
    Re: Thoughts about Python

    PPNTWIMBXFFC@sp ammotel.com (Marco Aschwanden) writes:
    [color=blue]
    > Hi
    >
    > I don't have to talk about the beauty of Python and its clear and
    > readable syntax... but there are a few things that striked me while
    > learning Python.
    >
    > I have collected those thoughts. I am sure there are many discussions
    > on the "problems" mentioned here. But I had this thoughts without
    > looking into any forums or anything... it is kind of feedback.
    >
    > Thanks for this marvellous language,
    > Marco
    >
    >
    >
    > *** Problem: clumsy static class methods
    >
    > In order to create a static method we have to use a the builtin
    > staticmethod(fu nction):
    >
    > class C (object):
    > def f(arg1, arg2, ...): ...
    > f = staticmethod(f)[/color]

    See PEP 318 (and current discussion on python-dev).
    [color=blue]
    > Why? The speciality of a "static" method is: It has no access to any
    > instance vars. The following class is easier to read and understand
    > what a static method is about... as a positive side-effect: self is
    > not available and it can't be used!
    >
    > class c (object):
    > def staticMethod(ar g1, arg2, ...):
    > # self is not handed in... hence I can't use the instance vars
    > pass
    > def normalMethod(se lf, arg1, arg2, ...):
    > pass
    >
    > There is no need for the builtin... as I understand it: the builtin is
    > a workaround...[/color]

    What's so special about self? I really don't like the idea of
    argument names keying this kind of change in behaviour.
    [color=blue]
    > *** Problem: clumsy properties for classes
    >
    > property( [fget[, fset[, fdel[, doc]]]])
    >
    > class C(object):
    > def getx(self): return self.__x
    > def setx(self, value): self.__x = value
    > def delx(self): del self.__x
    > x = property(getx, setx, delx, "I'm the 'x' property.")
    >
    >
    > I don't like this one either. It is not necessary because it describes
    > something that should be clear by looking at the class/code. A
    > convention would make the syntax clearer and more intuitive and by
    > looking at the definition of a method you would know: This is a
    > getter, setter or deleter. My proposal:
    >
    > all getters start with __get__
    > all setters start with __set__
    > all deleters start with __del__
    >
    > If someone uses:
    >
    > prop.x = 5
    >
    > Python checks whether the var 'x' exists on prop. If it does - it is
    > set. If it doesn't exist Python checks for '__set__x' if it doesn't
    > exist either... a AttributeError is raised:
    >
    >
    > class PropertyExample (object):
    > """A demonstration class for the property idea.
    >
    > This class is used afterwards as follows:
    > prop = PropertyExample ()
    > prop.x = 5 # __set__x(self, 5) is called behind the scenes
    > print prop.x # __get__x(self) is called behind the scenes
    > del prop.x # __del__x(self) is called behind the scenes"""
    >
    > def __init__(self):
    > self.__x = None
    >
    > def __del__x(self):
    > del self.__x
    > def __get__x(self):
    > return self.__x
    > def __set__x(self, value):
    > self.__x = value[/color]

    You seem really fond of magic names...

    By the way, Python 2.2 introduced the capacity for staticmethods and
    properties and consciously decided not to add syntax for the same
    until there was some experience in using these things. So it's known
    that there is some discomfort here, but it's not yet clear (to me, at
    least) what a good syntax *is*. I hope you're not too offended if I
    say that your suggestion doesn't seem instantly wonderful.
    [color=blue]
    > *** Problem: Many builtins are not necessary[/color]

    Pah. So what? If you want minimailty scheme is over there ====>
    [color=blue]
    > Many builtins are not necessary. To name a few: min / max / len
    >
    > This functions should be defined on the class:[/color]

    Says you!

    [...]
    [color=blue]
    > *** Problem: tuples are not necessary[/color]

    Says you! Here's a hint: hash([]).

    [...][color=blue]
    > *** Problem: builtins list() dict() ...
    >
    > A list, a dictionary, a str, an int, a float are builtin functions...
    >
    > myList = list()
    > myDict = dict()
    > myString = str(45)[/color]

    Pedantry: no they're not, they're builtin types.

    I think you might be expecting something other of Python than what it
    is. Nothing you suggest is completely ridiculous, just, well,
    slightly un-Pythonic. I suggest you continue using Python for a few
    more weeks and read your list again.

    Cheers,
    mwh

    --
    MARVIN: Oh dear, I think you'll find reality's on the blink again.
    -- The Hitch-Hikers Guide to the Galaxy, Episode 12

    Comment

    • Duncan Booth

      #3
      Re: Thoughts about Python

      PPNTWIMBXFFC@sp ammotel.com (Marco Aschwanden) wrote in
      news:15c2d03b.0 402240311.395f5 382@posting.goo gle.com:
      [color=blue]
      > I have collected those thoughts. I am sure there are many discussions
      > on the "problems" mentioned here. But I had this thoughts without
      > looking into any forums or anything... it is kind of feedback.[/color]

      I think you should spend a bit of time reading the PEPs and the python-dev
      mailing list archives. A lot of what you say has been discussed previously,
      and it would be good if you could take the earlier discussion on board and
      then see where your thoughts lead you.
      [color=blue]
      >
      > *** Problem: clumsy static class methods
      >[/color]
      This has been widely discussed elsewhere and various solutions have been
      proposed.
      [color=blue]
      >
      > *** Problem: clumsy properties for classes
      >[/color]
      As for static methods various ways to improve this have been suggested. You
      should read the discussions on python-dev to see the various viewpoints.
      [color=blue]
      >
      > *** Problem: Many builtins are not necessary
      >
      > Many builtins are not necessary. To name a few: min / max / len
      >
      > This functions should be defined on the class:
      >
      > ["I", "like", "Python"].len()
      > "I".len()
      > {1:"I", "2":"like", 3:"Python"}.len ()
      > (1,2,3,4).len()[/color]

      The advantage of min and max as builtins are that they work on any
      sequence. In particular they work on iterators. Having functions that apply
      to an arbitrary sequence avoids a lot of potential code duplication.
      [color=blue]
      > "Throwing away" this builtins would flatten the alreay flat learning
      > curve once more (you don't have to learn that many builtins) ... these
      > functions belong to the class and they are naturally expected there.
      > One weakness of a language as (Visual)Basic, PHP, ... is its payload
      > of available functions... Python's OO helps here to diminish the need
      > for lots of functions.[/color]

      There are other builtins I would throw away first. Note that you can't
      actually throw any of these builtins away: one of Pythons great strengths
      are the lengths it goes to to maintain backward compatibility. Some of the
      less useful builtins are being relegated to backwaters of the
      documentation, but they will remain as builtins for the foreseeable future.
      [color=blue]
      >
      >
      > *** Problem: tuples are not necessary
      >
      > Throw them away in the long run - for now make them depracted. It is
      > hard to argue in favour of tuples. There might to 2 reason:
      >
      > 1. It is MUCH faster than a list
      > 2. We can't live without an immutable list[/color]

      Forget the speed and memory difference. The main argument for tuples as a
      separate type are to use as dictionary keys. How do you propose to handle
      dictionary keys without tuples?
      [color=blue]
      >
      > *** Problem: builtins list() dict() ...
      >
      > A list, a dictionary, a str, an int, a float are builtin functions...[/color]

      No they aren't. They are types, not functions.
      [color=blue]
      >
      > myList = list()
      > myDict = dict()
      > myString = str(45)
      >
      > The list-function instantiates a new list... it is actually nothing
      > but an overloaded List class. Why are the handed in as functions? In a
      > OO environment it should be more the instatiation of a class rather
      > than a function and classes start with an uppercase letter:
      >
      > myList = List()
      > myDict = Dict()
      > myString = String(45)
      >[/color]

      So they don't follow your naming convention. If this is a big problem for
      you, then add some new globals in your own programs. The type 'file' is
      already aliased as 'open'. You can't remove the existing builtins (since
      that would break the library), but there is nothing to stop you adding your
      own either in the __builtin__ module, or as a separate module containing
      your aliases.

      FWIW, I agree that the builtins that exist aren't the best choice for type
      names --- too often they collide with the 'obvious' variable names that
      python newcomers choose and then they wonder why their call to 'str' blow
      up when they used a variable 'str' a few lines earlier.

      Comment

      • Matthias

        #4
        Re: Thoughts about Python

        Duncan Booth <me@privacy.net > writes:
        [color=blue]
        > PPNTWIMBXFFC@sp ammotel.com (Marco Aschwanden) wrote in
        > news:15c2d03b.0 402240311.395f5 382@posting.goo gle.com:[color=green]
        > > *** Problem: Many builtins are not necessary
        > >
        > > Many builtins are not necessary. To name a few: min / max / len
        > >
        > > This functions should be defined on the class:
        > >
        > > ["I", "like", "Python"].len()
        > > "I".len()
        > > {1:"I", "2":"like", 3:"Python"}.len ()
        > > (1,2,3,4).len()[/color]
        >
        > The advantage of min and max as builtins are that they work on any
        > sequence. In particular they work on iterators. Having functions that apply
        > to an arbitrary sequence avoids a lot of potential code duplication.[/color]

        Do you mean code duplication on the user side? Or code duplication in
        Python's implementations ? In the latter case, it seems strange to
        force inconsistent method/function usage on thousands of developers
        just in order to save a couple of lines in Python's source code.

        To me, Python's builtins are by far not a "problem", but I admit that
        I never understood why astring.len() doesn't work.

        Comment

        • Duncan Booth

          #5
          Re: Thoughts about Python

          Matthias <no@spam.pls> wrote in
          news:36wu11g8um s.fsf@goya03.ti .uni-mannheim.de:
          [color=blue][color=green]
          >> The advantage of min and max as builtins are that they work on any
          >> sequence. In particular they work on iterators. Having functions that
          >> apply to an arbitrary sequence avoids a lot of potential code
          >> duplication.[/color]
          >
          > Do you mean code duplication on the user side? Or code duplication in
          > Python's implementations ? In the latter case, it seems strange to
          > force inconsistent method/function usage on thousands of developers
          > just in order to save a couple of lines in Python's source code.[/color]

          I mean code duplication on the user side. A function that operates on every
          iterator or sequence type is far more useful than a protocol that more
          often than not wouldn't be implemented.
          [color=blue]
          >
          > To me, Python's builtins are by far not a "problem", but I admit that
          > I never understood why astring.len() doesn't work.
          >[/color]
          Because it would have to begin and end with two underscores (thats the
          naming convention for special methods), and astring.__len__ () already does
          what you want. But I think it is mostly for historical reasons.

          Comment

          • Aahz

            #6
            Re: Thoughts about Python

            In article <15c2d03b.04022 40311.395f5382@ posting.google. com>,
            Marco Aschwanden <PPNTWIMBXFFC@s pammotel.com> wrote:[color=blue]
            >
            >*** Problem: Many builtins are not necessary
            >
            >Many builtins are not necessary. To name a few: min / max / len
            >
            >This functions should be defined on the class:
            >
            >["I", "like", "Python"].len()
            >"I".len()
            >{1:"I", "2":"like", 3:"Python"}.len ()
            >(1,2,3,4).len( )
            >
            >"Throwing away" this builtins would flatten the alreay flat learning
            >curve once more (you don't have to learn that many builtins) ... these
            >functions belong to the class and they are naturally expected there.
            >One weakness of a language as (Visual)Basic, PHP, ... is its payload
            >of available functions... Python's OO helps here to diminish the need
            >for lots of functions.[/color]

            "Practicali ty beats purity"; if you're not familiar with that, start up
            an interactive Python session and type "import this".

            In this case, this means that Guido thinks that len() is such a common
            usage that it works better as a function than a method.
            --
            Aahz (aahz@pythoncra ft.com) <*> http://www.pythoncraft.com/

            "Do not taunt happy fun for loops. Do not change lists you are looping over."
            --Remco Gerlich, comp.lang.pytho n

            Comment

            • Terry Reedy

              #7
              Re: Thoughts about Python


              "Marco Aschwanden" <PPNTWIMBXFFC@s pammotel.com> wrote in message
              news:15c2d03b.0 402240311.395f5 382@posting.goo gle.com...[color=blue]
              > I have collected those thoughts. I am sure there are many discussions
              > on the "problems" mentioned here.[/color]

              Yes, there have been. Do read some if you are really interested.
              [color=blue]
              >*** Problem: clumsy properties for classes[/color]

              The problem is currently under discussion. Your fix is based on thinking
              'self' to be a keyword, which it is not, instead of a usage convention for
              English language programmers. Python is not <language x>.
              [color=blue]
              > class c (object):
              > def staticMethod(ar g1, arg2, ...): pass
              > # self is not handed in... hence I can't use the instance vars[/color]

              Yes it is and yes you can if this method called on an instance. You have
              simply called the instance 'arg1' instead of 'self'.
              [color=blue]
              > def normalMethod(se lf, arg1, arg2, ...):
              > pass[/color]

              If you follow this by normalMethod = staticmethod(no rmalMethod), then
              'self' is *not* an instance.
              Static methods are very rare. You left out a proposal for the more common
              and more useful classmethod.

              ....[color=blue]
              > Many builtins are not necessary.[/color]

              Many people agree.
              [color=blue]
              > To name a few: min / max / len[/color]

              But people wildly disagree on which should be axed.
              [color=blue]
              > This functions should be defined on the class:[/color]

              This syntax uniformatizing suggestion comes up about once a year. It
              overlooks the fact that uniformity is lost as soon as a user writes a
              sequence function (for instance, variance()). I know, we could abolish
              functions and only have methods. But if you want that, choose a different
              language.

              Even more, It also overlooks the tremendous advantages of generic
              programming with Python. If I write an iterable type, it can be used with
              any sequence function, current or future. Conversely, if I write a
              sequence (iterable) function, it can be used with any iterable object,
              current or future -- without subclassing or access to source code. Your
              proposed handcuff of requiring a specifc method for each type - function
              combinatin leads to an M*N explosion of code and coding work.

              Quiz: how would you rewrite map(len, ['abc', (1,2,3,4), [5,6]]) if len()
              were a method?
              [color=blue]
              >classes start with an uppercase letter:
              > myList = List()[/color]

              This appears to be a convention or rule you learned from another language.
              Though some Python programmers follow it, tt is not part of Python.

              Terry J. Reedy




              Comment

              • Terry Reedy

                #8
                Re: Thoughts about Python


                "Matthias" <no@spam.pls> wrote in message
                news:36wu11g8um s.fsf@goya03.ti .uni-mannheim.de...[color=blue]
                > Duncan Booth <me@privacy.net > writes:[color=green]
                > > The advantage of min and max as builtins are that they work on any
                > > sequence. In particular they work on iterators. Having functions that[/color][/color]
                apply[color=blue][color=green]
                > > to an arbitrary sequence avoids a lot of potential code duplication.[/color]
                >
                > Do you mean code duplication on the user side? Or code duplication in
                > Python's implementations ?[/color]

                Python's generic programming saves user code.

                Write a function taking an iterable argument and it can be used with any of
                the countable infinity of possible iterable types, current and future. For
                free, without having to subclass or otherwise attach the function as a
                method to each.

                Write an iterable type and it can be fed to any of the countable infinity
                of possible sequence functions, written and yet to be written. For free,
                without adding them all as methods, which is impossible anyway for future
                functions.
                [color=blue]
                > In the latter case,[/color]

                But it is both cases, so your consequent does not follow.
                [color=blue]
                > To me, Python's builtins are by far not a "problem", but I admit that
                > I never understood why astring.len() doesn't work.[/color]

                Because there is currently no process to make generic functions accessible
                (aliased) as specific methods. Possible (but not-serious) proposal: Add
                interface objects with attribute __takes__ being a set of functions which
                takes objects implementing that interface as a single argument. Give types
                a set of interfaces called __implements__. If attribute look-up fails,
                search __takes__ for interfaces in __implements__. But you now you have
                to explicitly register objects with the sets, and you still have problems
                with interfaces (virtual types) often being too narrow, too broad, and/or
                too numerous and what to do with multiparameter functions. Isn't
                len(astring) easier, as well as one char shorter?

                Terry J. Reedy




                Comment

                • OKB (not okblacke)

                  #9
                  Re: Thoughts about Python

                  Duncan Booth wrote:
                  [color=blue]
                  > The advantage of min and max as builtins are that they work on any
                  > sequence. In particular they work on iterators. Having functions
                  > that apply to an arbitrary sequence avoids a lot of potential code
                  > duplication.[/color]

                  Wouldn't subclassing be an appropriate solution? The most general
                  sequence class/type could define a len method and the others would
                  inherit it and override it if they have different length semantics. In
                  fact, Python already does this with the __len__ magic method. Having a
                  builtin function whose implementation is defined with a magically named
                  method seems an awkward design. Why not have just the method and do
                  away with the function?

                  --
                  --OKB (not okblacke)
                  Brendan Barnwell
                  "Do not follow where the path may lead. Go, instead, where there is
                  no path, and leave a trail."
                  --author unknown

                  Comment

                  • OKB (not okblacke)

                    #10
                    Re: Thoughts about Python

                    Terry Reedy wrote:
                    [color=blue]
                    > Quiz: how would you rewrite map(len, ['abc', (1,2,3,4), [5,6]]) if
                    > len() were a method?[/color]

                    [ a.len() for a in ['abc', (1,2,3,4), [5,6]] ]

                    --
                    --OKB (not okblacke)
                    Brendan Barnwell
                    "Do not follow where the path may lead. Go, instead, where there is
                    no path, and leave a trail."
                    --author unknown

                    Comment

                    • John Roth

                      #11
                      Re: Thoughts about Python


                      "Marco Aschwanden" <PPNTWIMBXFFC@s pammotel.com> wrote in message
                      news:15c2d03b.0 402240311.395f5 382@posting.goo gle.com...[color=blue]
                      > Hi
                      >
                      > I don't have to talk about the beauty of Python and its clear and
                      > readable syntax... but there are a few things that striked me while
                      > learning Python.
                      >
                      > I have collected those thoughts. I am sure there are many discussions
                      > on the "problems" mentioned here. But I had this thoughts without
                      > looking into any forums or anything... it is kind of feedback.
                      >
                      > Thanks for this marvellous language,
                      > Marco
                      >
                      >
                      >
                      > *** Problem: clumsy static class methods
                      >
                      > In order to create a static method we have to use a the builtin
                      > staticmethod(fu nction):
                      >
                      > class C (object):
                      > def f(arg1, arg2, ...): ...
                      > f = staticmethod(f)
                      >
                      > Why? The speciality of a "static" method is: It has no access to any
                      > instance vars. The following class is easier to read and understand
                      > what a static method is about... as a positive side-effect: self is
                      > not available and it can't be used![/color]

                      Since several people have already mentioned that the syntax
                      is a temporary expedient until such time as a better idea can
                      be agreed upon, I'll just add one thing. "self" is not a built-in.
                      There is no requirement that the first parameter of a method
                      be called "self", although it's easy enough to get that impression.
                      So it's not possible to distinguish static methods by not having
                      "self" as the first parameter.
                      [color=blue]
                      > *** Problem: clumsy properties for classes
                      >
                      > property( [fget[, fset[, fdel[, doc]]]])
                      >
                      > class C(object):
                      > def getx(self): return self.__x
                      > def setx(self, value): self.__x = value
                      > def delx(self): del self.__x
                      > x = property(getx, setx, delx, "I'm the 'x' property.")[/color]

                      [blah...]

                      There's nothing standing in your way of writing a
                      metaclass to do this, you know.
                      [color=blue]
                      > *** Problem: Many builtins are not necessary
                      >
                      > Many builtins are not necessary. To name a few: min / max / len
                      >
                      > This functions should be defined on the class:
                      >
                      > ["I", "like", "Python"].len()
                      > "I".len()
                      > {1:"I", "2":"like", 3:"Python"}.len ()
                      > (1,2,3,4).len()
                      >
                      > "Throwing away" this builtins would flatten the alreay flat learning
                      > curve once more (you don't have to learn that many builtins) ... these
                      > functions belong to the class and they are naturally expected there.
                      > One weakness of a language as (Visual)Basic, PHP, ... is its payload
                      > of available functions... Python's OO helps here to diminish the need
                      > for lots of functions.[/color]

                      That's a common complaint of OO purists about Python. Most
                      of them miss one rather obvious point: single inheritance languages
                      that have a root object tend to load that object with lots of utility
                      functions as methods, and then expect that all derived classes will
                      kowtow to them and not change their meaning. That makes it very
                      difficult to add new universal methods: you'll run into existing
                      classes that use them for something else.

                      Python's method of doing it takes universal method names
                      out of a different name space.
                      [color=blue]
                      > *** Problem: tuples are not necessary[/color]

                      Frankly, there is very little in any programming language that is
                      necessary. Back when I brushed up against computability theory,
                      I found that all programs can be written in a language with one operation:
                      a combination of subtract and conditional branch. That's hardly
                      practical, though. The question is whether a feature serves a useful
                      purpose.

                      Tuples serve two distinct purposes. One is as a cheap version
                      of a C struct: that is, a data structure in which each element
                      serves a conceptually different purpose.

                      The other is as a structure that is immutable so it can be used
                      as a key in a dict.

                      One thing to understand about this is that immutability is key:
                      dicts depend on having a hash key that is somehow derived
                      from the content of the object, and if the content of a key
                      changes that key will probably simply be unlocatable: it will be
                      filed in the dict under the old rather than the new hash code.

                      Ruby, for instance, does not have that restriction on hash
                      keys, but it's got other restrictions that are much easier
                      to trip over.

                      [color=blue]
                      > *** Problem: builtins list() dict() ...
                      >
                      > A list, a dictionary, a str, an int, a float are builtin functions...
                      >
                      > myList = list()
                      > myDict = dict()
                      > myString = str(45)
                      >
                      > The list-function instantiates a new list... it is actually nothing
                      > but an overloaded List class. Why are the handed in as functions? In a
                      > OO environment it should be more the instatiation of a class rather
                      > than a function and classes start with an uppercase letter:
                      >
                      > myList = List()
                      > myDict = Dict()
                      > myString = String(45)[/color]

                      I think we've discussed the built-in function versus object
                      attribute issue before.

                      John Roth


                      Comment

                      • Paul Prescod

                        #12
                        Re: Thoughts about Python

                        Terry Reedy wrote:
                        [color=blue]
                        >
                        > Quiz: how would you rewrite map(len, ['abc', (1,2,3,4), [5,6]]) if len()
                        > were a method?[/color]

                        map(lambda x: x.len(), ['abc', (1,2,3,4), [5,6]])

                        or

                        [x.len() for x in ['abc', (1,2,3,4), [5,6]]]
                        [color=blue][color=green]
                        >>classes start with an uppercase letter:
                        >>myList = List()[/color]
                        >
                        > This appears to be a convention or rule you learned from another language.
                        > Though some Python programmers follow it, tt is not part of Python.
                        > ...[/color]

                        It actually is a pretty good convention. There really is a pretty big
                        distinction between functions and types (isa, inheritance etc.) so it is
                        good to distinguish them. Also, many classes in the standard library use
                        upper-case classes. (e.g. UserList, Pickler, etc.)

                        Paul Prescod



                        Comment

                        • nnes

                          #13
                          Re: Thoughts about Python

                          PPNTWIMBXFFC@sp ammotel.com (Marco Aschwanden) wrote in message news:<15c2d03b. 0402240311.395f 5382@posting.go ogle.com>...[color=blue]
                          > Hi
                          >
                          > I don't have to talk about the beauty of Python and its clear and
                          > readable syntax... but there are a few things that striked me while
                          > learning Python.
                          >
                          > I have collected those thoughts. I am sure there are many discussions
                          > on the "problems" mentioned here. But I had this thoughts without
                          > looking into any forums or anything... it is kind of feedback.
                          >
                          > Thanks for this marvellous language,
                          > Marco
                          >
                          >
                          >
                          > *** Problem: clumsy static class methods
                          >
                          > In order to create a static method we have to use a the builtin
                          > staticmethod(fu nction):
                          >
                          > class C (object):
                          > def f(arg1, arg2, ...): ...
                          > f = staticmethod(f)
                          >
                          > Why? The speciality of a "static" method is: It has no access to any
                          > instance vars. The following class is easier to read and understand
                          > what a static method is about... as a positive side-effect: self is
                          > not available and it can't be used!
                          >
                          > class c (object):
                          > def staticMethod(ar g1, arg2, ...):
                          > # self is not handed in... hence I can't use the instance vars
                          > pass
                          > def normalMethod(se lf, arg1, arg2, ...):
                          > pass
                          >
                          > There is no need for the builtin... as I understand it: the builtin is
                          > a workaround...
                          >
                          >
                          >
                          > *** Problem: clumsy properties for classes
                          >
                          > property( [fget[, fset[, fdel[, doc]]]])
                          >
                          > class C(object):
                          > def getx(self): return self.__x
                          > def setx(self, value): self.__x = value
                          > def delx(self): del self.__x
                          > x = property(getx, setx, delx, "I'm the 'x' property.")
                          >
                          >
                          > I don't like this one either. It is not necessary because it describes
                          > something that should be clear by looking at the class/code. A
                          > convention would make the syntax clearer and more intuitive and by
                          > looking at the definition of a method you would know: This is a
                          > getter, setter or deleter. My proposal:
                          >
                          > all getters start with __get__
                          > all setters start with __set__
                          > all deleters start with __del__
                          >
                          > If someone uses:
                          >
                          > prop.x = 5
                          >
                          > Python checks whether the var 'x' exists on prop. If it does - it is
                          > set. If it doesn't exist Python checks for '__set__x' if it doesn't
                          > exist either... a AttributeError is raised:
                          >
                          >
                          > class PropertyExample (object):
                          > """A demonstration class for the property idea.
                          >
                          > This class is used afterwards as follows:
                          > prop = PropertyExample ()
                          > prop.x = 5 # __set__x(self, 5) is called behind the scenes
                          > print prop.x # __get__x(self) is called behind the scenes
                          > del prop.x # __del__x(self) is called behind the scenes"""
                          >
                          > def __init__(self):
                          > self.__x = None
                          >
                          > def __del__x(self):
                          > del self.__x
                          > def __get__x(self):
                          > return self.__x
                          > def __set__x(self, value):
                          > self.__x = value
                          >
                          >
                          >
                          > *** Problem: Many builtins are not necessary
                          >
                          > Many builtins are not necessary. To name a few: min / max / len
                          >
                          > This functions should be defined on the class:
                          >
                          > ["I", "like", "Python"].len()
                          > "I".len()
                          > {1:"I", "2":"like", 3:"Python"}.len ()
                          > (1,2,3,4).len()
                          >
                          > "Throwing away" this builtins would flatten the alreay flat learning
                          > curve once more (you don't have to learn that many builtins) ... these
                          > functions belong to the class and they are naturally expected there.
                          > One weakness of a language as (Visual)Basic, PHP, ... is its payload
                          > of available functions... Python's OO helps here to diminish the need
                          > for lots of functions.
                          >
                          >
                          > *** Problem: tuples are not necessary
                          >
                          > Throw them away in the long run - for now make them depracted. It is
                          > hard to argue in favour of tuples. There might to 2 reason:
                          >
                          > 1. It is MUCH faster than a list
                          > 2. We can't live without an immutable list
                          >
                          > Cons:
                          >
                          > 1. I don't think that tuples deliver a big performance gain.
                          > 2. Python makes so many "soft" conventions (eg.: don't use
                          > vars/methods with 2 leading underscores) but when it comes to tuples
                          > the immutable issue is very important... why? I hope the tuples will
                          > disappear in P3K.
                          >
                          >
                          > *** Problem: builtins list() dict() ...
                          >
                          > A list, a dictionary, a str, an int, a float are builtin functions...
                          >
                          > myList = list()
                          > myDict = dict()
                          > myString = str(45)
                          >
                          > The list-function instantiates a new list... it is actually nothing
                          > but an overloaded List class. Why are the handed in as functions? In a
                          > OO environment it should be more the instatiation of a class rather
                          > than a function and classes start with an uppercase letter:
                          >
                          > myList = List()
                          > myDict = Dict()
                          > myString = String(45)[/color]

                          I agree with you in all but that tuples are not
                          necessary. Lists are the ones that are actually a
                          hack for speed! :-)

                          In fully functional languages you would operate on your
                          list with something like:

                          lst=[1,2]
                          lst=lst.append( 3)
                          lst=lst.sort()
                          lst=lst.reverse ()
                          lst=lst.insert( 2,3)

                          count=lst.appen d(3).sort().rev erse().len()

                          1_ Do not try this at home kids, it will not work :)

                          2_ Hmm, tuples could grow these methods. Would be
                          confusing as hell though. >:-}

                          3_ I prefer reading from left to right instead from right
                          to left (it makes the parenthesis less confusing too).
                          Compare to:

                          count=len(rever sed(sorted(appe nded(lst,3)))).

                          Maybe I should learn Hebrew :-)
                          Or we could always change it to

                          $ lst|append -3|sort|reverse| len

                          (in the end all are just filter patterns :))

                          4_ If the python interpreter was smart enough sort()
                          could return a new list or sort in place depending on the
                          context: i.e.
                          lst=lst.sort() eq. lst.sort()
                          newlst=lst.sort () where lst is never used again eq.
                          lst.sort();newl st=lst;del lst, etc
                          but that would be against the pythons philosophy of
                          keeping the interpreter small, lean and simple.

                          Inmutable types are usually less "magical" than their
                          mutable counterpart.

                          For instance:
                          [color=blue][color=green][color=darkred]
                          >>> lst1=[1,2]
                          >>> lst2=lst1
                          >>> lst2.append(3)
                          >>> lst1[/color][/color][/color]
                          [1, 2, 3][color=blue][color=green][color=darkred]
                          >>> lst2[/color][/color][/color]
                          [1, 2, 3][color=blue][color=green][color=darkred]
                          >>> tup1=(1,2)
                          >>> tup2=tup1
                          >>> tup2=tup2+(3,)
                          >>> tup1[/color][/color][/color]
                          (1, 2)[color=blue][color=green][color=darkred]
                          >>> tup2[/color][/color][/color]
                          (1, 2, 3)[color=blue][color=green][color=darkred]
                          >>>[/color][/color][/color]

                          Do you think a newbie would expect that a modification
                          on one variable would have a effect on another?

                          Comment

                          • Marco Aschwanden

                            #14
                            Re: Thoughts about Python

                            > I think you should spend a bit of time reading the PEPs...[color=blue]
                            > what you say has been discussed previously,
                            > then see where your thoughts lead you.[/color]

                            I will do that.
                            [color=blue]
                            > Forget the speed and memory difference. The main argument for tuples as a
                            > separate type are to use as dictionary keys. How do you propose to handle
                            > dictionary keys without tuples?[/color]

                            Maybe I don't get the point here: Why do dictionaries need tuples to
                            work? I know that tuples can be used as keys... but how many times do
                            you need tuples as dictionary keys (it would be simple to turn a list
                            into an immutable string if really needed ("::".join(["a","b"]). But
                            maybe tuples are used within dictionary in a way I don't know. If you
                            could clarify on this point I will never ever say anything about
                            "useless" tuples... instead I will start asking for "immutable
                            dictionaries" 8o)

                            [color=blue][color=green]
                            > > A list, a dictionary, a str, an int, a float are builtin functions...[/color]
                            >
                            > No they aren't. They are types, not functions.[/color]

                            functions... types... classes... simplicity at its best. But then it
                            was stated I am a very un-pythonic thinker.
                            [color=blue][color=green]
                            > > The list-function instantiates a new list... it is actually nothing
                            > > but an overloaded List class. Why are the handed in as functions? In a
                            > > OO environment it should be more the instatiation of a class rather
                            > > than a function and classes start with an uppercase letter:
                            > >
                            > > myList = List()
                            > > myDict = Dict()
                            > > myString = String(45)
                            > >[/color]
                            >
                            > So they don't follow your naming convention.[/color]

                            Well, yeah, this is true and isn't. It is true that there is no rule
                            how to name a class. To me a list / dict / string is a (basic) class
                            (you take about types - the manuals does also) but why introduce new
                            words, when the class-idiom is enough to explain everything. You want
                            a list, well instantiate a list class --> list = List().
                            What is easier to explain: If you want to create an object some kind,
                            you need a class which starts with an uppercase letter. Or do you
                            rather like to explain: well, if you want a list or dictionary you use
                            list() or dict() but if you want an attribute error object you use:
                            AttributeError( ). Whenever you want an object, you check the manuals
                            to see, whether you need upper- or lower-class instantiation. 8o)
                            It is true, no one tells you that class names have to start with
                            uppercase letter (and I could create an alias). But look into the
                            standard library and you will find that my naming scheme for classes
                            prevails. Intuition tells me hence: I want a list instance therefore I
                            need to call the _L_ist-Class. And yes, talking about the
                            _f_ile-function/class/type... that returns a "file-object": I would
                            write it with a leading uppercase letter: I want to instantiate a
                            file-object hence I need to new a _F_ile-class.
                            I am well aware that it wasn't possible to derive a List / Dict / ...
                            until lately. Most probably the distinction between types and classes
                            stems from this time.


                            Anyway, I see that my "feedback" was very unreflected. These were
                            thoughts I had while learning and it was wrong to mention them so
                            unprocessed. Without consulting the PEP, reading comp.lang.pytho n
                            discussions...

                            Sorry,
                            Marco

                            Comment

                            • Marco Aschwanden

                              #15
                              Re: Thoughts about Python

                              > > *** Problem: clumsy static class methods
                              [color=blue]
                              > See PEP 318 (and current discussion on python-dev).[/color]

                              Thanks for the hint.
                              [color=blue][color=green]
                              > > class c (object):
                              > > def staticMethod(ar g1, arg2, ...):
                              > > # self is not handed in... hence I can't use the instance vars
                              > > pass
                              > > def normalMethod(se lf, arg1, arg2, ...):
                              > > pass
                              > >[/color][/color]
                              [color=blue]
                              > What's so special about self? I really don't like the idea of
                              > argument names keying this kind of change in behaviour.[/color]

                              One gets to get used to passing in self into class member functions.
                              It is there and I learned to live with it (self). What separates a
                              static method from a non-static-method is its (var) context. A static
                              method is not allowed to use instance vars. This can be easily
                              achieved by dropping the self-arg in the method definition... but as I
                              can see by browsing through PEP 318: A lot of "decorators " are wished
                              and this proposal only "solves" the static method case. Forget about
                              it - it was just a thought.
                              [color=blue][color=green]
                              > > *** Problem: clumsy properties for classes[/color][/color]
                              [color=blue][color=green]
                              > > My proposal:
                              > >
                              > > all getters start with __get__
                              > > all setters start with __set__
                              > > all deleters start with __del__
                              > >[/color]
                              >
                              > You seem really fond of magic names...
                              >[/color]
                              No, it uses an idea that Python uses in many places: __len__ is used
                              with the len-function, __init__ is used when a class is instantiated,
                              __getitem__ is used with [], etc. etc. so why not use the same scheme
                              for class properties. But I can live with you saying:
                              [color=blue]
                              > I hope you're not too offended if I
                              > say that your suggestion doesn't seem instantly wonderful.[/color]

                              No problem. 8o)
                              [color=blue][color=green]
                              > > *** Problem: Many builtins are not necessary[/color]
                              >
                              > Pah. So what? If you want minimailty scheme is over there ====>[/color]

                              No, I am not asking for minimality. I am asking for a clean design - a
                              string has a length therefore a string has the method len(). How many
                              "object oriented" languages do you know that give you the size/length
                              of an object by calling an external function? Except for Python I know
                              no other... and I know: Java, C++, Ruby (and others but not so object
                              oriented ones).
                              [color=blue][color=green]
                              > > Many builtins are not necessary. To name a few: min / max / len
                              > >
                              > > This functions should be defined on the class:[/color]
                              >
                              > Says you!
                              >[/color]

                              Yeah, thanks for the convincing arguments against it. 8o)
                              [color=blue]
                              >[color=green]
                              > > *** Problem: tuples are not necessary[/color]
                              >
                              > Says you! Here's a hint: hash([]).
                              >
                              > [...][/color]

                              I suppose this is the argument: list are not immutable that is why
                              they cannot be used a dict key... I wonder how many people use a tuple
                              as dict key. This seems to be a common practice to justify its own
                              "type". I admit, I can think of simple workarounds when there wouldn't
                              be tuples (eg. Instead of transforming a list into tuple why not
                              transforming it into a string).
                              [color=blue]
                              > I think you might be expecting something other of Python than what it
                              > is. Nothing you suggest is completely ridiculous, just, well,
                              > slightly un-Pythonic.[/color]

                              un-Pythonic... this bytes ... hmm... why? Reading your comments it
                              does not justify such a hard judgment - or does it?

                              Thanks anyway for your response and the hint for PEP 318,
                              Greetings,
                              Marco

                              Comment

                              Working...