Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
124 views
in Technique[技术] by (71.8m points)

python - Is it bad to store all instances of a class in a class field?

I was wondering if there is anything wrong (from a OOP point of view) in doing something like this:

class Foobar:
    foobars = {}
    def __init__(self, name, something):
        self.name = name
        self.something = something

        Foobar.foobars[name] = self

Foobar('first', 42)
Foobar('second', 77)

for name in Foobar.foobars:
    print name, Foobar.foobars[name]

EDIT: this is the actual piece of code I'm using right now

from threading import Event
class Task:
    ADDED, WAITING_FOR_DEPS, READY, IN_EXECUTION, DONE = range(5)
    tasks = {}
    def __init__(self, name, dep_names, job, ins, outs, uptodate, where):
        self.name = name
        self.dep_names = [dep_names] if isinstance(dep_names, str) else dep_names
        self.job = job
        self.where = where
        self.done = Event()
        self.status = Task.ADDED
        self.jobs = []
        # other stuff...
        Task.tasks[name] = self
    def set_done(self):
        self.done.set()
        self.status = Task.DONE
    def wait_for_deps(self):
        self.status = Task.WAITING_FOR_DEPS
        for dep_name in self.dep_names:
            Task.tasks[dep_name].done.wait()
        self.status = Task.READY
    def add_jobs_to_queues(self):
        jobs = self.jobs
        # a lot of stuff I trimmed here
        for w in self.where: Queue.queues[w].put(jobs)
        self.status = Task.IN_EXECUTION
    def wait_for_jobs(self):
        for j in self.jobs: j.wait()
    #[...]

As you can see I need to access the dictionary with all the instances in the wait_for_deps method. Would it make more sense to have a global variable instead of a class field? I could be using a wrong approach here, maybe that stuff shouldn't even be in a method, but it made sense to me (I'm new to OOP)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Yes. It's bad. It conflates the instance with the collection of instances.

Collections are one thing.

The instances which are collected are unrelated.

Also, class-level variables which get updated confuse some of us. Yes, we can eventually reason on what's going on, but the Standard Expectation? is that state change applies to objects, not classes.


 class Foobar_Collection( dict ):
     def __init__( self, *arg, **kw ):
         super( Foobar_Collection, self ).__init__( *arg, **kw ):
     def foobar( self, *arg, **kw ):
         fb= Foobar( *arg, **kw )
         self[fb.name]= fb
         return fb

 class Foobar( object ):
     def __init__( self, name, something )
         self.name= name
         self.something= something

fc= Foobar_Collection()
fc.foobar( 'first', 42 )
fc.foobar( 'second', 77 ) 

for name in fc:
    print name, fc[name]

That's more typical.


In your example, the wait_for_deps is simply a method of the task collection, not the individual task. You don't need globals.

You need to refactor.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...