Skip Huffman
Skip Huffman

Reputation: 5449

create a dictionary of class names by an attribute of each class

I have a set of classes that have as one of their attributes a url. I would like to build a dictionary of those classes, keyed by that url. Here is the code I have come up with:

class pagesByUrl(dict):
    "a cross reference of pages by url rather than object name"
    def __init__(self):
        pages={}
        for page in dir(xxxPages):
            try:
                pgAttr=getattr(xxxPages, page)
                pg=pgAttr('dummybrowser')
                pages[pg.url] = page
            except (KeyError, TypeError, AttributeError):
                pass
        print pages #At this point, the dictionary is good.
        self=pages
        print self #Also here, still just what I want.




pg=pagesByUrl()
print "pg is:", pg #But here, pg is an empty dictionary.  

What can I do to have this class instantiate as the dictionary that I want?

Upvotes: 1

Views: 121

Answers (2)

rook
rook

Reputation: 6240

Check out __new__() method for instance creation, if you want to have pure "type dict"

class dictA(dict):
    def __new__(self):
        self._pages={"one":1, "two":2}
        return self._pages

class pagesByUrl(dict):
    def __init__(self):
        _pages = {"one":1, "two":2}
        dict.__init__(self)
        self.update(_pages)

d = {"one":1, "two":2}
print type(d)
print d

d = dictA()
print type(d)
print d

d = pagesByUrl()
print type(d)
print d

Output:

<type 'dict'>
{'two': 2, 'one': 1}
<type 'dict'>
{'two': 2, 'one': 1}
<class '__main__.pagesByUrl'>
{'two': 2, 'one': 1}

Upvotes: 0

mgilson
mgilson

Reputation: 309891

class pagesByUrl(dict):
    "a cross reference of pages by url rather than object name"
    def __init__(self):
        dict.__init__(self) #!
        pages={}
        for page in dir(xxxPages):
            try:
                pgAttr=getattr(xxxPages, page)
                pg=pgAttr('dummybrowser')
                pages[pg.url] = page
            except (KeyError, TypeError, AttributeError):
                pass

       self.update(pages)
       #Alternatively, forgo the previous `dict.__init__(self)` and the 
       #previous line and do:
       #dict.__init__(self,pages)

If you do self = pages, you're simply replacing the local name self in the __init__ function with the pages dictionary. You're not actually mutating the dictionary which was self.

Of course, at this point, there's no need to have the pages dict at all -- We can just use self:

class pagesByUrl(dict):
    "a cross reference of pages by url rather than object name"
    def __init__(self):
        dict.__init__(self)
        for page in dir(xxxPages):
            try:
                pgAttr=getattr(xxxPages, page)
                pg=pgAttr('dummybrowser')
                self[pg.url] = page
            except (KeyError, TypeError, AttributeError):
                pass

Upvotes: 3

Related Questions