Python class gotcha with scope?

B

billy

I don't quite understand why this happens. Why doesn't b have its own
version of r? If r was just an int instead of a dict, then it would.
.... r = {}
.... def setn(self, n):
.... self.r["f"] = n
....{'f': 4}

thanks,

billy
 
V

Vincent

I don't quite understand why this happens. Why doesn't b have its own
version of r? If r was just an int instead of a dict, then it would.

...     r = {}
...     def setn(self, n):
...             self.r["f"] = n
...>>> a = foo()
{'f': 4}

thanks,

billy


class Foo:
def __init__(self):
self.r = {}
def setn(self,n):
self.r['f'] = n

a = Foo()
a.setn(3)
a.r
{'f': 3}
b = Foo()
b.r
{}
 
V

Vincent

I don't quite understand why this happens. Why doesn't b have its own
version of r? If r was just an int instead of a dict, then it would.
...     r = {}
...     def setn(self, n):
...             self.r["f"] = n
...>>> a = foo()
a.setn(4)
b = foo()
b.r
{'f': 4}

billy

class Foo:
    def __init__(self):
        self.r = {}
    def setn(self,n):
        self.r['f'] = n

a = Foo()
a.setn(3)
a.r
{'f': 3}
b = Foo()
b.r
{}

you defined r as class-level variable.
and i defined r as instance-level variable.
 
C

Carl Banks

I don't quite understand why this happens. Why doesn't b have its own
version of r? If r was just an int instead of a dict, then it would.

...     r = {}
...     def setn(self, n):
...             self.r["f"] = n
...>>> a = foo()
{'f': 4}

r is a class attribute, that is, it is attacted to the class itself.
Look at what happens when you enter foo.r at the interactive prompt:
{'f': 4}


You want an instance attribute, a value attached to the instance of
the class. You create those in the __init__ method:


class foo:
def __init__(self):
self.r = {}
def setn(self,n):
self.r["n"] = n



Carl Banks
 
B

billy

great, thanks for the quick responses :)


I don't quite understand why this happens. Why doesn't b have its own
version of r? If r was just an int instead of a dict, then it would.
...     r = {}
...     def setn(self, n):
...             self.r["f"] = n
...>>> a = foo()
a.setn(4)
b = foo()
b.r

r is a class attribute, that is, it is attacted to the class itself.
Look at what happens when you enter foo.r at the interactive prompt:

{'f': 4}

You want an instance attribute, a value attached to the instance of
the class.  You create those in the __init__ method:

class foo:
    def __init__(self):
        self.r = {}
    def setn(self,n):
        self.r["n"] = n

Carl Banks
 
D

Dennis Lee Bieber

I don't quite understand why this happens. Why doesn't b have its own
version of r? If r was just an int instead of a dict, then it would.
1) You defined it at the class level
2) The lookup first looks for "self.r" on the instance, doesn't
find it, so looks at the class space
3) Dictionaries and lists are mutable -- you are changing the
contents "in place" (ie, in the class level object). Integers (all
numerics, tuples, and strings) are not mutable, so any "assignment" to
the name ("self.whatever = xxx") reattaches the name (self.whatever) to
the new object (xxx).

Compare the difference between your
... r = {}
... def setn(self, n):
... self.r["f"] = n
...

and one that used

def setn(self, n):
self.r = {"f" : n}

which is creating a new dictionary and then binding "self.r" to it
without changing the class level "r".
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top