Is it possible to have instance variables in subclasses of builtins?

Discussion in 'Python' started by Kenneth McDonald, Jun 15, 2004.

  1. I've recently used subclasses of the builtin str class to good effect.
    However, I've been unable to do the following:

    1) Call the constructor with a number of arguments other than
    the number of arguments taken by the 'str' constructor.

    2) Create and use instance variables (eg. 'self.x=1') in
    the same way that I can in a 'normal' class.

    As an example of what I mean, here's a short little session:

    >>> class a(str):

    .... def __init__(self, a, b):
    .... str.__init__(a)
    .... self.b = b
    ....
    >>> x = a("h", "g")

    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    TypeError: str() takes at most 1 argument (2 given)
    >>>


    (hmm, on reflection, I shouldn't have used 'a' as a
    parameter to __init__--but that's merely bad
    style, not the cause of the error :) )

    On the other hand, this example works:

    >>> class b(str):

    .... def __init__(self, x):
    .... str.__init__(x)
    ....
    >>> x = b("h")
    >>> x

    'h'
    >>>


    Is it possible to circumvent the above restrictions?

    Thanks,
    Ken
    Kenneth McDonald, Jun 15, 2004
    #1
    1. Advertising

  2. Kenneth McDonald

    Larry Bates Guest

    The following might work for you:

    from UserString import UserString
    class b(UserString):
    def __init__(self, x, y, z):
    self.y=y
    self.z=z
    self.x=x
    UserString.__init__(self, x)
    return

    >>> x=b('h', 1, 2)
    >>> x.z

    2
    >>> x.y

    1
    >>> x.x

    'h'
    >>> len(x)

    1

    Uses old UserString class.

    HTH,
    Larry Bates
    Syscon, Inc.


    "Kenneth McDonald" <> wrote in message
    news:.2wire.net...
    > I've recently used subclasses of the builtin str class to good effect.
    > However, I've been unable to do the following:
    >
    > 1) Call the constructor with a number of arguments other than
    > the number of arguments taken by the 'str' constructor.
    >
    > 2) Create and use instance variables (eg. 'self.x=1') in
    > the same way that I can in a 'normal' class.
    >
    > As an example of what I mean, here's a short little session:
    >
    > >>> class a(str):

    > ... def __init__(self, a, b):
    > ... str.__init__(a)
    > ... self.b = b
    > ...
    > >>> x = a("h", "g")

    > Traceback (most recent call last):
    > File "<stdin>", line 1, in ?
    > TypeError: str() takes at most 1 argument (2 given)
    > >>>

    >
    > (hmm, on reflection, I shouldn't have used 'a' as a
    > parameter to __init__--but that's merely bad
    > style, not the cause of the error :) )
    >
    > On the other hand, this example works:
    >
    > >>> class b(str):

    > ... def __init__(self, x):
    > ... str.__init__(x)
    > ...
    > >>> x = b("h")
    > >>> x

    > 'h'
    > >>>

    >
    > Is it possible to circumvent the above restrictions?
    >
    > Thanks,
    > Ken
    Larry Bates, Jun 15, 2004
    #2
    1. Advertising

  3. Kenneth McDonald

    Russell Blau Guest

    "Kenneth McDonald" <> wrote in message
    news:.2wire.net...
    > I've recently used subclasses of the builtin str class to good effect.
    > However, I've been unable to do the following:
    >
    > 1) Call the constructor with a number of arguments other than
    > the number of arguments taken by the 'str' constructor.
    >
    > 2) Create and use instance variables (eg. 'self.x=1') in
    > the same way that I can in a 'normal' class.
    >
    > As an example of what I mean, here's a short little session:
    >
    > >>> class a(str):

    > ... def __init__(self, a, b):
    > ... str.__init__(a)
    > ... self.b = b
    > ...
    > >>> x = a("h", "g")

    > Traceback (most recent call last):
    > File "<stdin>", line 1, in ?
    > TypeError: str() takes at most 1 argument (2 given)
    > >>>


    The problem is that "str" is an immutable type. Therefore, to change the
    constructor, you need to override the __new__ method. See
    http://www.python.org/2.2.1/descrintro.html#__new__

    Here's an example:

    >>> class two(str):

    def __new__(cls, a, b):
    return str.__new__(cls, a)
    def __init__(self, a, b):
    self.b = b

    >>> z = two("g", "h")
    >>> z

    'g'
    >>> z.b

    'h'

    Note that both arguments (a and b) get passed to both the __new__ and
    __init__ methods, and each one just ignores the one it doesn't need.


    --
    I don't actually read my hotmail account, but you can replace hotmail with
    excite if you really want to reach me.
    Russell Blau, Jun 16, 2004
    #3
    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. chris brat
    Replies:
    1
    Views:
    617
    chris brat
    May 10, 2006
  2. Eric Lilja
    Replies:
    6
    Views:
    438
    Eric Lilja
    Feb 26, 2005
  3. Replies:
    6
    Views:
    318
    Peter Otten
    Mar 8, 2006
  4. dackz
    Replies:
    0
    Views:
    476
    dackz
    Feb 6, 2007
  5. Gareth Adams
    Replies:
    2
    Views:
    142
    Phrogz
    Dec 11, 2007
Loading...

Share This Page