Extending built-in objects/classes

Discussion in 'Python' started by Jon Clements, Jul 3, 2006.

  1. Jon Clements

    Jon Clements Guest

    Hi All,

    I've reached the point in using Python where projects, instead of being
    like 'batch scripts', are becoming more like 'proper' programs.

    Therefore, I'm re-designing most of these and have found things in
    common which I can use classes for. As I'm only just starting to get
    into classes, I see that new style classes are thte way to go, so will
    be using those. I come from a C++ background, and understand I need to
    adjust my thinking in certain ways - I have read
    http://www.geocities.com/foetsch/python/new_style_classes.htm.


    As a really simple class, I've decided to make a 'str' to include a
    'substr' function. Yes, I know this can be done using slicing, and
    effectively this is what substr would do: something like;

    class mystr(str):
    """" My rather rubbish but trying to be simple custom string class
    """
    def substr(self,start,length,pad=False):
    """
    Return str of (up to) _length_ chars, starting at _start_ which
    is 1 offset based.
    If pad is True, ensure _length_ chars is returned by padding
    with trailing whitespace.
    """"
    return self.<what>[ (start-1): (start-1)+length ]

    Ignore the fact pad isn't implemented...

    <what> should be the actual string value of the string object: How do I
    work out what this is?
    Secondly, I'm not 100% sure what I need for the __init__; is str's
    __init__ implicitly called, or do I need to call str's __init__ in
    mystr's (I seem to remember seeing some code which did this, as well as
    calling super()).

    Any critiscm is appreciated.

    Many thanks,

    Jon.
     
    Jon Clements, Jul 3, 2006
    #1
    1. Advertising

  2. Jon Clements

    Guest

    My experiance is mostly with old-style classes, but here goes.

    first off, the <what> question is actually easier than you think.
    After all, self is an instance of a string, so self[3:4] would grab
    the slice of characters between 3 and 4 =)

    as for __init__, what I have found is that if you do not include an
    __init__ function, the parent class's __init__ gets inherited, just
    like any other function, so you dont need one. If you have multiple
    inheritance, however, you must include an __init__ which calls the
    __init__ on every parent, otherwise only the first parent's gets
    called.
     
    , Jul 3, 2006
    #2
    1. Advertising

  3. Jon Clements

    Jon Clements Guest

    wrote:
    > My experiance is mostly with old-style classes, but here goes.
    >
    > first off, the <what> question is actually easier than you think.
    > After all, self is an instance of a string, so self[3:4] would grab
    > the slice of characters between 3 and 4 =)
    >


    That's kind of funky - I like it. However, I'd still like to know what
    <what> technically is - any ideas on how to find out?

    > as for __init__, what I have found is that if you do not include an
    > __init__ function, the parent class's __init__ gets inherited, just
    > like any other function, so you dont need one. If you have multiple
    > inheritance, however, you must include an __init__ which calls the
    > __init__ on every parent, otherwise only the first parent's gets
    > called.


    Thanks for your post: it's most appreciated.

    Cheers,

    Jon.
     
    Jon Clements, Jul 3, 2006
    #3
  4. Jon Clements

    John Machin Guest

    On 3/07/2006 7:55 PM, Jon Clements wrote:
    > wrote:
    >> My experiance is mostly with old-style classes, but here goes.
    >>
    >> first off, the <what> question is actually easier than you think.
    >> After all, self is an instance of a string, so self[3:4] would grab
    >> the slice of characters between 3 and 4 =)
    >>

    >
    > That's kind of funky - I like it. However, I'd still like to know what
    > <what> technically is - any ideas on how to find out?


    You have already been told: you don't need "self.<what>", you just write
    "self" ... self *is* a reference to the instance of the mystr class that
    is being operated on by the substr method.

    You did ask for criticism: here's what's intended to be constructive
    criticism: you can often find out answers a lot faster by actually
    trying it out yourself. E.g. do I need an __init__() method?

    |>> class mystr(str):
    .... def substr(self, start, length):
    .... return self[start-1:start-1+length]
    ....
    |>> foo = mystr('abcdef')
    |>> foo
    'abcdef'
    |>> foo.substr(2, 3)
    'bcd'
    |>> mystr.substr(foo, 2, 3)
    'bcd'

    No __init__(), no <what>, it just works!

    HTH,
    John
     
    John Machin, Jul 3, 2006
    #4
  5. Jon Clements

    Jon Clements Guest

    John Machin wrote:
    (snip)
    >
    > You have already been told: you don't need "self.<what>", you just write
    > "self" ... self *is* a reference to the instance of the mystr class that
    > is being operated on by the substr method.
    >

    (snip)

    I get that; let me clarify why I asked again.

    As far as I'm aware, the actual representation of a string needn't be
    the same as its 'physical' value. ie, a string could always appear in
    uppercase ('ABCD'), while stored as 'aBcd'. If I need to guarantee that
    substr always returned from the physical representation and not the
    external appearance, how would I do this? Or, would self, always return
    internal representation, (if so, how would I get external appearance?).

    Or I could be talking complete _beep_ - in which case I apologise.

    Jon.
     
    Jon Clements, Jul 3, 2006
    #5
  6. Jon Clements

    John Machin Guest

    On 3/07/2006 10:01 PM, Jon Clements wrote:
    > John Machin wrote:
    > (snip)
    >> You have already been told: you don't need "self.<what>", you just write
    >> "self" ... self *is* a reference to the instance of the mystr class that
    >> is being operated on by the substr method.
    >>

    > (snip)
    >
    > I get that; let me clarify why I asked again.
    >
    > As far as I'm aware, the actual representation of a string needn't be
    > the same as its 'physical' value. ie, a string could always appear in
    > uppercase ('ABCD'), while stored as 'aBcd'. If I need to guarantee that
    > substr always returned from the physical representation and not the
    > external appearance, how would I do this? Or, would self, always return
    > internal representation, (if so, how would I get external appearance?).
    >
    > Or I could be talking complete _beep_ - in which case I apologise.
    >
    > Jon.
    >

    The external appearance of an object is produced by repr and str
    methods. These transform the internal value into a human-readable (and
    Python-compilable, in the case of repr) format. When you are
    subclassing, these methods would normally be inherited.

    Let's transpose your question into the realm of floats. A float is
    usually a 64-bit gizmoid with about 53 bits of mantissa, a sign bit, and
    the rest is for the exponent. The external representations are character
    strings like '3.3333333333333333e-021'. You want to subclass float so
    that you can add handy methods like squared(). You would like it to be
    as simple as:

    def squared(self):
    return self * self

    There are two possibilities:
    (a) It just works; e.g. print myfloat(1.1).squared() produces 1.21
    (b) It doesn't work, you get some mysterious exception like

    TypeError: can't multiply sequence by non-int

    which you decode as meaning that it doesn't like you trying to multiply
    two character strings together, and you have to code the return
    expression as self.__internal__ * self.__internal__ or something like that.

    1. Which of these possibilities do you think is more
    useful/elegant/plausible?
    2. [Stop me if you've heard this one before] When you try it out, what
    happens?
    3. Have you ever seen any indication in the manuals, tutorials, books,
    code published online, etc etc as to which possibility has been implemented?

    HTH,
    John
     
    John Machin, Jul 3, 2006
    #6
    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. Kenneth
    Replies:
    4
    Views:
    725
    Tony Morris
    Nov 11, 2004
  2. Alex Martelli
    Replies:
    3
    Views:
    303
    Achim Dahlhoff
    Nov 29, 2005
  3. 7stud
    Replies:
    11
    Views:
    713
    Dennis Lee Bieber
    Mar 20, 2007
  4. GVDC
    Replies:
    0
    Views:
    363
  5. G.
    Replies:
    10
    Views:
    176
Loading...

Share This Page