James Biederbeck James Biederbeck - 2 months ago 16
Python Question

I want a class' __init__ to add the object to a list, but I want to prevent redundancy and "if self not in objectlist" isn't working

I'm writing a script that checks multiple sources for weather data, then parses them for an some scripts on Scripting Layer for Android. The google API stopped working, so this is a hacked together replacement for the old weather module.

I made a class called "weatherdata", and I want to have all instances of the class add themselves to a list called "weatherobjects", for shenanigans like this:

for source in weatherobjects:

Here's the catch: each time the function that fetches the weather is called, it causes the objects to run their
method (I think this is technically called a constructor method?) without destroying the objects, or clearing the list. This is intentional. The problem comes when the function is called more than once in the lifetime of the module, and and the objects get redundantly added to the list. This seems like a potential source of a memory leak.

Here's the

class weatherdata():
def __init__(self, url, unit = 'f'):
self.url = url
self.unit = unit
print(self) #debug statement, please ignore
if self not in weatherobjects:
if self.url.count("yahoo"):
self.yahoo = True
self.yahoo = False

And the troublesome function:

def fetch_weather(location=98661, hl='', weatherobjects= []):
yahoo = weatherdata(yahoo_url, 'f')
wunderground = weatherdata(wunderground_url, 'f')
data = {}
data['city'] = 'Vancouver'
data['temperature'] = wunderground.temp
data['conditions'] = 'foo'
return data

Here's some shell output for context:

>>> weatherobjects
[<__main__.weatherdata object at 0x01F8BDF0>, <__main__.weatherdata object at 0x02035B70>]
>>> for i in range(3):
... fetch_weather()
{'city': 'Vancouver', 'conditions': 'foo', 'temperature': '66.7'}
{'city': 'Vancouver', 'conditions': 'foo', 'temperature': '66.7'}
{'city': 'Vancouver', 'conditions': 'foo', 'temperature': '66.7'}
>>> weatherobjects
[<__main__.weatherdata object at 0x01F8BDF0>, <__main__.weatherdata object at 0x02035B70>, <__main__.weatherdata object at 0x01FA2E10>, <__main__.weatherdata object at 0x01FA2FB0>, <__main__.weatherdata object at 0x02035C30>, <__main__.weatherdata object at 0x02035E10>, <__main__.weatherdata object at 0x02035DF0>, <__main__.weatherdata object at 0x02035D10>]
>>> len(weatherobjects)

As you can see, there's a lot of redundancy in the list. Is it possible to do this in the
method? Or do I need to have a main function do something like


So two years later, I have found the answer while working on something else, and come back to this. Putting aside other issues with my code, I think I should have defined the list in the class (before instantiation), rather than as a global.

My desired behavior was like this example, taken from the Python Docs:

 class Dog:

    tricks = []             # mistaken use of a class variable

    def __init__(self, name):
        self.name = name

    def add_trick(self, trick):

    >>> d = Dog('Fido')
    >>> e = Dog('Buddy')
    >>> d.add_trick('roll over')
    >>> e.add_trick('play dead')
    >>> d.tricks                
    ['roll over', 'play dead']

This is inappropriate because dogs don't have a hivemind, but the behavior is not explicitly disapproved of in the docs, so I'm going to roll with it. I WANT my weatherobjects to have a hivemind.

So instead of something like this,

global weatherobjectslist
class weathersource():
    def __init__(self, weatherobjectlist):

My desired behavior is produced by this:

class weathersource():
    weathersourcelist = []

    def __init__(self, name):
        self.name = name

Now, I can check weathersource.weathersourcelist for a list of all my objects.

To put this more generically, here's an example with the same behavior, and some output:

>>> class person():
    people= []
    def __init__(self, name):
        self.name = name

>>> a,b,c = person('bob'), person('joe'), person('steve')

>>> for individual in person.people: