frozenset/subclassing/keyword args

M

Mark E. Fenner

Hello all,

I was migrating some code from sets.ImmutableSet to frozenset and noticed
the following:

******code********
#!/usr/bin/env python

from sets import ImmutableSet


class MSet1(ImmutableSet):
def __init__(self, iterArg, myName="foo"):
ImmutableSet.__init__(self, iterArg)
self.name = myName


class MSet2(frozenset):
def __init__(self, iterArg, myName="foo"):
frozenset.__init__(self, iterArg)
self.name = myName


m1 = MSet1([1,2,3], myName = "donkey")
print m1
print m1.name

m2 = MSet2([1,2,3], myName = "kong")
print m2
print m2.name
*********end code**********

*********run**********
MSet1([1, 2, 3])
donkey
Traceback (most recent call last):
File "./setTest.py", line 22, in ?
m2 = MSet2([1,2,3], myName = "kong")
TypeError: frozenset() does not take keyword arguments
*********end run********

I'm missing something and couldn't find it in the docs.

Speaking of which, in the docs at the bottom of the description of the
builtin set/frozenset, there is a link to a page describing differences
between the builtin sets and the sets module sets. This link is broken
locally and on the python.org docs.
Locally, it reads:
file:///usr/share/doc/python-docs-2.4.2/html/lib/module-comparison-to-builtin-set.html

While it should read:
file:///usr/share/doc/python-docs-2.4.2/html/lib/comparison-to-builtin-set.html

Regards,
Mark
 
K

Kent Johnson

Mark said:
Speaking of which, in the docs at the bottom of the description of the
builtin set/frozenset, there is a link to a page describing differences
between the builtin sets and the sets module sets. This link is broken
locally and on the python.org docs.
Locally, it reads:
file:///usr/share/doc/python-docs-2.4.2/html/lib/module-comparison-to-builtin-set.html

While it should read:
file:///usr/share/doc/python-docs-2.4.2/html/lib/comparison-to-builtin-set.html

A little further down the page it says "See About this document... for information on suggesting changes." If you click the link there it will tell you how to submit a doc bug which is the best way to get this fixed.

Kent
 
B

Bengt Richter

Hello all,

I was migrating some code from sets.ImmutableSet to frozenset and noticed
the following:

******code********
#!/usr/bin/env python

from sets import ImmutableSet


class MSet1(ImmutableSet):
def __init__(self, iterArg, myName="foo"):
ImmutableSet.__init__(self, iterArg)
self.name = myName


class MSet2(frozenset):
def __init__(self, iterArg, myName="foo"):
frozenset.__init__(self, iterArg)
self.name = myName


m1 = MSet1([1,2,3], myName = "donkey")
print m1
print m1.name

m2 = MSet2([1,2,3], myName = "kong")
print m2
print m2.name
*********end code**********

*********run**********
MSet1([1, 2, 3])
donkey
Traceback (most recent call last):
File "./setTest.py", line 22, in ?
m2 = MSet2([1,2,3], myName = "kong")
TypeError: frozenset() does not take keyword arguments
*********end run********

I'm missing something and couldn't find it in the docs.

Without researching it, I would guess that you have to override __new__
so as not to pass through the myName arg to the otherwise inherited and
called-with-all-arguments __new__ of the base class. You could take care
of the myName arg in the __new__ method too (by temporarily binding the
instance returned by frozenset.__new__ and assigning the name attribute
before returning the instance), or you can define __init__ to do that part.
See many various posted examples of subclassing immutable types.

Regards,
Bengt Richter
 
M

Mark E. Fenner

Without researching it, I would guess that you have to override __new__
so as not to pass through the myName arg to the otherwise inherited and
called-with-all-arguments __new__ of the base class.

Regards,
Bengt Richter

Bengt,

Thanks as always! Python's rabbit holes always go a little deeper then
you've currently gone. My one irritation is that it seems that the error
message could give some indication of where the problem lies. "bad args to
__new__", "immutable's bypass init", "black voodoo ahead" ... but I know,
efficiency, conciseness, other concerns, etc. etc. Doesn't mean I can't
gripe about it!

As you said, there are a number of threads on this. Consulting those gave a
quick three line solution, shown below.

Regards,
Mark

P.S. Here's what I should have been doing:

******************** start file *********************
#!/usr/bin/env python

from sets import ImmutableSet

class MSet1(ImmutableSet):
def __init__(self, iterArg, myName="foo"):
ImmutableSet.__init__(self, iterArg)
self.name = myName



# works
class MSet2(frozenset):
def __new__(cls, itrarg, *args, **kwargs):
return frozenset.__new__(cls, itrarg)

def __init__(self, iterArg, myName="foo"):
frozenset.__init__(self, *iterArg)
self.name = myName

# broken
class MSet3(frozenset):
def __init__(self, iterArg, myName="foo"):
frozenset.__init__(self, *iterArg)
self.name = myName

m1 = MSet1([1,2,3], myName = "donkey")
print m1
print m1.name

m2 = MSet2([1,2,3], myName = "mario")
print m2
print m2.name

m3 = MSet3([1,2,3], myName = "kong")
print m3
print m3.name
******************* end file ****************

************* sample run ******************
MSet1([1, 2, 3])
donkey
MSet2([1, 2, 3])
mario
Traceback (most recent call last):
File "./setTest.py", line 33, in ?
m3 = MSet3([1,2,3], myName = "kong")
TypeError: frozenset() does not take keyword arguments
************** end run ***********************
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top