Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
bug or feature?
#1
Hi people!

I have been playing around with python a little and came across this:
consider the following code in Python3

class THING:
    def __init__(self):
        
        self.number=10
        self.valueDict={
            0: self.number
        }
    def __getitem__(self,index):
        return self.valueDict[index]
    
    def __setitem__(self,index,newVal):
        if index==0:
            self.number=newVal
does not work consistently:
Output:
IN:a=THING() IN:a[0] Out: 10 IN:a[0]=9 IN:a[0] Out: 10
The dictionary seems to address a different variable but it is not so:

class THING:
    def __init__(self):
        
#      self.number=10
        self.valueDict={
            0: self.number
        }
    def __getitem__(self,index):
        return self.valueDict[index]
    
    def __setitem__(self,index,newVal):
        if index==0:
            self.number=newVal
results after initialisation are:

Error:
AttributeError: 'THING' object has no attribute 'number'
my Workaround is:
class THING:
    def __init__(self):
        
        self.number=10
        self.valueDict={
            0: lambda: self.number
        }
    def __getitem__(self,index):
        return self.valueDict[index]()
    
    def __setitem__(self,index,newVal):
        if index==0:
            self.number=newVal
Output:
IN:e=THING() IN:e[0] Out: 10 IN:e[0]=9 IN:e[0] Out: 9
Now why is that, or better what is the purpose? ...and I know I could have just used a map for __setitem__ as well

Cheers
Reply
#2
For your first code: self.valueDict is referenced by the getter but not the setter. Your class doesn't extend anything that would make accessing the internal dictionary automatic in the setter, so that's expected behavior.

For your second code: you tried to access a variable that wasn't defined. Could you be more specific about what the expected behavior was?

Could you describe more, preferably including examples, what exactly the behavior you want is? It's not clear since your setter only ever sets for one value right now, and silently ignores others.
Reply
#3
Hello :)

A different example of what I don´t understand:
The code is now altered a little...

class THING:
    def __init__(self):

        self.number=10
        self.valueDict={
            0: self.number
        }
    def __getitem__(self,index):
        return self.valueDict[index]

    def __setitem__(self,index,newVal):
        self.valueDict[index]=newVal
Output:
IN:e=THING() IN:e[0] Out: 10 IN:e[0]=9 IN:e[0] Out: 9 IN: #now the shock: IN:e.number Out: 10
I expect the variable to be changed but it is in fact not changed

Cheers
Reply
#4
When the dictionary is created, self.number's value is stored, the dictionary itself doesn't keep track of that variable. This is by design. If you want them both updated, you'll have to update both. You can make self.number a property that accesses the dictionary, which would give your class a similar interface. But why have both?
Reply
#5
Why is that shocking? You're altering the dict's value, but not the 'self.number' value.
Reply
#6
(Dec-06-2016, 07:24 PM)nilamo Wrote: Why is that shocking? You're altering the dict's value, but not the 'self.number' value.
I can see how someone might think that they were binding the variable, rather than the value, into the dictionary. Especially with the literal notation. It's just not the case.
Reply
#7
ohhh I see.
Thank you!
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020