Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > overloading *something

Reply
Thread Tools

overloading *something

 
 
James Stroud
Guest
Posts: n/a
 
      11-08-2005
Hello All,

How does one make an arbitrary class (e.g. class myclass(object)) behave like
a list in method calls with the "*something" operator? What I mean is:

myobj = myclass()

doit(*myobj)

I've looked at getitem, getslice, and iter. What is it if not one of these?

And, how about the "**something" operator?

James

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
Reply With Quote
 
 
 
 
Ron Adam
Guest
Posts: n/a
 
      11-08-2005


James Stroud wrote:

> Hello All,
>
> How does one make an arbitrary class (e.g. class myclass(object)) behave like
> a list in method calls with the "*something" operator? What I mean is:


You need to base myclass on a list if I understand your question.

class myclass(list):
def __init__(self, *items):
# change items if needed
# initate other attributes if needed
list.__init__(self, *items)

Then the line below should work. Of course it won't do much with out
something in it.

> myobj = myclass()
>
> doit(*myobj)
>
> I've looked at getitem, getslice, and iter. What is it if not one of these?
>
> And, how about the "**something" operator?
>
> James


A dictionary would be pretty much the same except subclassed from a
dictionary of course.

Cheers,
Ron



 
Reply With Quote
 
 
 
 
Alex Martelli
Guest
Posts: n/a
 
      11-08-2005
Ron Adam <(E-Mail Removed)> wrote:

> James Stroud wrote:
>
> > Hello All,
> >
> > How does one make an arbitrary class (e.g. class myclass(object)) behave
> > like a list in method calls with the "*something" operator? What I mean
> > is:

>
> You need to base myclass on a list if I understand your question.


Not necessary, all you need is __iter__:

>>> def f(*a): print a

....
>>> class X(object):

.... def __iter__(self): return iter(xrange(4))
....
>>> f(*X())

(0, 1, 2, 3)
>>>


> > I've looked at getitem, getslice, and iter. What is it if not one of these?


Obviously James hadn't looked at __iter__ in the RIGHT way!


> > And, how about the "**something" operator?
> >
> > James

>
> A dictionary would be pretty much the same except subclassed from a
> dictionary of course.


I believe this one is correct (but I have not checked in-depth!).


Alex
 
Reply With Quote
 
Leif K-Brooks
Guest
Posts: n/a
 
      11-08-2005
James Stroud wrote:
> Hello All,
>
> How does one make an arbitrary class (e.g. class myclass(object)) behave like
> a list in method calls with the "*something" operator? What I mean is:
>
> myobj = myclass()
>
> doit(*myobj)


Make it iterable:

>>> class Foo(object):

... def __iter__(self):
... yield 1
... yield 2
... yield 3
...
>>> def bar(*args):

... print args
...
>>> bar(*Foo())

(1, 2, 3)


> And, how about the "**something" operator?


Use a dictionary.
 
Reply With Quote
 
Ron Adam
Guest
Posts: n/a
 
      11-08-2005


Alex Martelli wrote:
> Ron Adam <(E-Mail Removed)> wrote:
>
>
>>James Stroud wrote:


>>>And, how about the "**something" operator?
>>>
>>>James

>>
>>A dictionary would be pretty much the same except subclassed from a
>>dictionary of course.

>
>
> I believe this one is correct (but I have not checked in-depth!).
>
>
> Alex


A quick test shows the error message to be very specific in this case,
where as the *something error message requests a more general sequence.


>>> def foo(**b): pass

....
>>> class a: pass

....
>>> foo(**a)

Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: foo() argument after ** must be a dictionary


Ron
 
Reply With Quote
 
James Stroud
Guest
Posts: n/a
 
      11-08-2005
On Monday 07 November 2005 20:36, Alex Martelli wrote:
> > > I've looked at getitem, getslice, and iter. What is it if not one of
> > > these?

>
> Obviously James hadn't looked at __iter__ in the RIGHT way!


I was attempting to re-define iter of a subclassed list, to find the "magic"
method, but it didn't work. I'm not sure if "wrong" and "right" apply here:

py> class NewList(list):
.... def __iter__(self):
.... return iter([8,9,10])
....
py>
py> n = NewList([1,2,3])
py>
py> def doit(*args):
.... print args
....
py> doit(*n)
(1, 2, 3)
py> for x in iter(n):
.... print x
....
8
9
10


--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
Reply With Quote
 
Peter Otten
Guest
Posts: n/a
 
      11-08-2005
James Stroud wrote:

> I was attempting to re-define iter of a subclassed list, to find the
> "magic" method, but it didn't work.


>>> class List(list):

.... def __iter__(self): return iter("abc")
....
>>> a = List([1,2,3])
>>> list(a)

['a', 'b', 'c']
>>> tuple(a)

(1, 2, 3)

list-to-tuple conversion is optimized for performance -- basically a
memcopy() of the internal data. As with a similar peculiarity with
file.write() and the print statement, the problem could be shunned if
python would check for the exact class instead of a test that is equivalent
to isinstance().

Peter

 
Reply With Quote
 
James Stroud
Guest
Posts: n/a
 
      11-09-2005
On Monday 07 November 2005 20:36, Alex Martelli wrote:
> Ron Adam <(E-Mail Removed)> wrote:
> > James Stroud wrote:
> > > Hello All,
> > >
> > > How does one make an arbitrary class (e.g. class myclass(object))
> > > behave like a list in method calls with the "*something" operator? What
> > > I mean is:

[snip]
> > A dictionary would be pretty much the same except subclassed from a
> > dictionary of course.

>
> I believe this one is correct (but I have not checked in-depth!).


Does anyone else find the following annoying:


py> from UserDict import UserDict
py> aud = UserDict({"a":1, "b":2})
py> def doit(**kwargs):
.... print kwargs
....
py> aud
{'a': 1, 'b': 2}
py> doit(**aud)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: doit() argument after ** must be a dictionary


UserDict should be isomorphic with a dict. The fact that it is not in this
case seems terribly un-pythonic to me.

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
Reply With Quote
 
Robert Kern
Guest
Posts: n/a
 
      11-09-2005
James Stroud wrote:

> Does anyone else find the following annoying:
>
> py> from UserDict import UserDict
> py> aud = UserDict({"a":1, "b":2})
> py> def doit(**kwargs):
> ... print kwargs
> ...
> py> aud
> {'a': 1, 'b': 2}
> py> doit(**aud)
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> TypeError: doit() argument after ** must be a dictionary
>
> UserDict should be isomorphic with a dict. The fact that it is not in this
> case seems terribly un-pythonic to me.


UserDict only exists for backwards compatibility with old code that used
it before one could subclass from dict directly. Don't use it if you can
avoid it. UserDict only ever exposed the Python-side interface of dicts.
It couldn't expose the C-side interface, and it's the C-side interface
that **kwds is using.

--
Robert Kern
http://www.velocityreviews.com/forums/(E-Mail Removed)

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter

 
Reply With Quote
 
James Stroud
Guest
Posts: n/a
 
      11-09-2005
On Tuesday 08 November 2005 22:54, Robert Kern wrote:
> James Stroud wrote:
> > Does anyone else find the following annoying:
> >
> > py> from UserDict import UserDict
> > py> aud = UserDict({"a":1, "b":2})
> > py> def doit(**kwargs):
> > ... print kwargs
> > ...
> > py> aud
> > {'a': 1, 'b': 2}
> > py> doit(**aud)
> > Traceback (most recent call last):
> > File "<stdin>", line 1, in ?
> > TypeError: doit() argument after ** must be a dictionary
> >
> > UserDict should be isomorphic with a dict. The fact that it is not in
> > this case seems terribly un-pythonic to me.

>
> UserDict only exists for backwards compatibility with old code that used
> it before one could subclass from dict directly. Don't use it if you can
> avoid it. UserDict only ever exposed the Python-side interface of dicts.
> It couldn't expose the C-side interface, and it's the C-side interface
> that **kwds is using.


That **kwargs insists on using the C-side interface is precisely the annoyance
to which I am referring. I should be able to write a dictionary-like
interface in python and **kwargs should in turn be able to use it. If the
retort is that the C-side interface is used for performance, my retort to the
retort is that an isinstance() is already being called somewhere, so no
additional tests would need to be made to make **kwargs more generalized.

James

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
RE: Overloading __init__ & Function overloading Iyer, Prasad C Python 4 09-30-2005 08:01 PM
Re: Overloading __init__ & Function overloading Fredrik Lundh Python 0 09-30-2005 03:59 PM
Overloading __init__ & Function overloading Iyer, Prasad C Python 3 09-30-2005 02:17 PM
Re: Overloading __init__ & Function overloading Steve Holden Python 0 09-30-2005 01:58 PM
Re: Overloading __init__ & Function overloading Fredrik Lundh Python 0 09-30-2005 01:53 PM



Advertisments