shared variables.

Ok I’ll try to rephrase my problem, since my first attempt was cryptic.

If I have:

class foobar():

self.foofoo = 'string of text'

def foo():

   result =  self.foofoo + 'and stuff'

print result

or something like that, the function foo sees the variable self.foofoo in it’s class… because they are

relatives. Right?

but if I have

class foobar():

self.foofoo = 'string of text'

class barfoo():

print self.foofoo

The two classes don’t talk to each other, so IDLE would say that self.foofoo isn’t defined.

So if I wanted to use self.foofoo in both classes is the only way to do this is make foofoo

a global?

Does that make better sense this time?

That would actually be something like:

class foobar:
foofoo = ‘string of text’

def init(self):
self.barbar = “something”

def foo(self):

   result =  self.foofoo + 'and stuff'

   print result

or something like that, the function foo sees the variable self.foofoo in it’s class… because they are

relatives. Right?

Basically, within the function “foo” it can see the variable “foofoo” because when it is called, the specific instance of the class is passed in as the first argument. You can then grab whatever attributes you want from the instance.

So, if you do this:

myfoo = foobar()

You are creating an instance of your foobar class.

Then when you call a method on it:

myfoo.foo()

Another way to spell that line is actually: foobar.foo(myfoo) – in fact that’s sort of what’s going on behind the scenes. It’s calling the “foo” function on the “foobar” class, but passing in your current instance as the first argument… so that instance becomes “self”. If there are any variables stored on self, you can access them via “self.attribute”.

Now, if you set a variable in the class definition(like you seemed to be doing), it becomes a class variable and not an instance variable. They look the same when you read them (“self.foobar” would return the same value if its a class or instance variable), but if you were to call “self.foobar = 5” within any code on the instance, it would overshadow that class variable. For that one instance, “foobar” would return 5; for any other instances of the class, it’d return the original value. That may or may not be desirable: sometimes its quite useful to establish ‘defaults’ that can be adjusted class-wide, but overridden on a per-instance basis. It just depends on what you’re doing.

Easy way to demonstrate that is:

class foo:
… bar = “Starting”
f_one = foo()
f_two = foo()
f_one.bar
f_two.bar

f_one.bar = “Middle”
f_one.bar
f_two.bar
foo.bar = “Ending”
f_one.bar
f_two.bar

Anyways, I wax verbosely… the “related” comment just seemed like it might inspire confusion if you think about it that way :slight_smile:

but if I have

class foobar():

self.foofoo = 'string of text'

class barfoo():

print self.foofoo

The two classes don’t talk to each other, so IDLE would say that self.foofoo isn’t defined.

So if I wanted to use self.foofoo in both classes is the only way to do this is make foofoo

a global?

There’s many ways to address this; in the end it sort of depends on just how much shared state you need to have between individual classes and the nature of that state.

Globals are certainly a possibility, and sometimes that’s the best-- but often not.

If you have a lot of state shared between different classes, a configuration object may be useful. That can be a class, a module, or a dictionary – whatever suits your purposes.

For example:

···

class foobar(object):
def init(self, state):
self.state = state

    self.state["something"] = "My something!"

class barfoo(object):
def init(self, state):
self.state = state

def dosomething(self):
    if 'something' in self.state:
        return self.state['something'] + ' and someting else!'

    else:
        return 'Oh no! foobar didn't set anything for me to do!'

if name == “main”:
config = {}
f = foobar(config)
b = barfoo(config)
print b.dosomething()


It just depends, again, on what the information is you need to share among the classes. A lot of times I prefer to keep classes as stupid as possible, and pass in them only the specific things they need to know. Other times they need to interact with each-other, and so I pass into one a reference to another: that way it can call into that other one to find out anything it needs to know. Sometimes their interaction is more complicated, and I use a “pubsub” type solution(although I prefer pydispatcher) to have them announce various information and anyone interested catches it and stores it for later. And sometimes a global really just is the best way to go. Or a shared dictionary, as above.

I just prefer to keep globals to things like… constants :slight_smile:

HTH,

–Stephen

class foobar:
foofoo = ‘string of text’

def init(self):
self.barbar = “something”

def foo(self):
   result =  self.foofoo + 'and stuff'
   print result

And yeah, I see I totally screwed that display up :slight_smile: I was attempting to just show the “you don’t use self in the class body” and, “i think you actually intend to do this stuff in init instead of in the class body”. Bah, I suck :slight_smile:

–S

Perfect! Thanks, it makes sense.

The answer I was looking for.

class foobar:

def init(self):

self.foo = ‘alphabet soup’

class f_one:

def init(self):

my_foo = foobar()

print my_foo.foo

I’ve seen it before, and I don’t know why I didn’t remember.

but seeing it this way, I’m sure I’ll never forget

Thanks!

From:
Stephen Hansen

To: wxpython-users@lists.wxwidgets.org

Sent: Friday, 01 August, 2008 20:21

Subject: Re: [wxpython-users] shared variables.

class foobar:
foofoo = ‘string of text’

def __init__(self):
        self.barbar = "something"
def foo(self):
       result =  self.foofoo + 'and stuff'
       print result

And yeah, I see I totally screwed that display up :slight_smile: I was attempting to just show the “you don’t use self in the class body” and, “i think you actually intend to do this stuff in init instead of in the class body”. Bah, I suck :slight_smile:

–S



wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

···

----- Original Message -----

Steve Freedenburg wrote:

The two classes don't talk to each other, so IDLE would say that self.foofoo isn't defined.
So if I wanted to use self.foofoo in both classes is the only way to do this is make foofoo
a global?

Another good approach to take is to make foofoo be a member of another class, and give each instance of the other classes a reference to an instance of the shared class.

class Data:
  pass

class Foo:
  def __init__(self, data):
    self.data = data
    self.data.foofoo = "string of text"

class Bar:
  def __init__(self, data):
    self.data = data
  def show(self):
    print self.data.foofoo

myData = Data()
myFoo = Foo(myData)
myBar = Bar(myData)
myBar.show()

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!