开发者

Using a global MANIFEST for object execution. Is there a better way?

开发者 https://www.devze.com 2023-03-23 08:40 出处:网络
I find myself repeating a common pattern when trying to execute code across multiple objects. Arg_list_one = [\"first\",\"second\", \"so on\"]

I find myself repeating a common pattern when trying to execute code across multiple objects.

Arg_list_one = ["first","second", "so on"]
Arg_list_two = ["first","second", "so on"]


MANIFEST = [ ]

class connection(object):
    def __init__(self, args):
        ...
        MANIFEST.append(self)
    def Run(self):
        ...

connection(Arg_list_one)
connection(Arg_list_two)

[conn.Run() for conn in MANIFEST]

Is this a 开发者_开发知识库pattern (or anti-pattern)? Or just something that I made up?

Are there other, better, ways of doing this?


Why would you need a list of all objects ever created? Many of those may belong to completely unrelated pieces of your application! A given piece of code shouldn't assume it's the only one to user a class. Especially since there's usually no need to:

  • A function creates a bunch of objects and then does something to all of them? Put the objects into a temporary, locally-scoped list.
  • Need to share some objects between functions? Put them in a list, pass the list to whoever should see the objects.
  • Instances of some class share some of these object? Make a list of them and put them in the class.
  • Et cetera, you see where this is going.

A more practical and less stylistic issue is that this list would keep every single object of that class that's ever instanciated alive forever. And they say one can't create memory leaks in Python... (This can be avoided with weak reference, but would make the code much more complex to transparently remove dead references.)

The solution is barely more typing and saves you a whole lot of headaches later on. Next you'll use local variables to save yourself a return?

connections = [Connection(arg_list_one), Connection(arg_list_two)]
for connection in connections:
    connection.run()

That said, there may be situations where such a list may be useful (with a fix for said memory leak, of course). I just don't see anything close to that in your example, and I think such situations are very rare.


I would suggest moving the manifest into the class. If it's really being used as a class variable, make it one.

class connection(object):
    MANIFEST = [ ]
    def __init__(self, args):
        ...
        self.MANIFEST.append(self)
    def Run(self):
        ...
    @classmethod
    def RunAll(cls):
        for conn in cls.MANIFEST:
            conn.Run()

connection(Arg_list_one)
connection(Arg_list_two)

conn.RunAll()

Also, if there are a lot of objects, your method will aggregate a long list of Nones (or whatever Run returns), so you're probably better off with a normal for loop.

Edit: The memory leak issue is a good point. If you do this, use the special __del__ method to remove the object from the list when it's deleted.

Edit 2: Actually, I think you'd need to do this in a close() method or something, because __del__ will never be called while there is a reference in the list.

0

精彩评论

暂无评论...
验证码 换一张
取 消