1

For some reason I have a class with a python getter acting like a setter...I have no idea why this is happening. If anyone could help me that would be much appriciated. :) This is my code

class Testclass():
    def __init__(self):
        self._testvar = None

    @property
    def testvar(self):
        return self._testvar

    @testvar.setter
    def testvar(self, value):
        assert False

testObj = Testclass()
testObj.testvar = "test"
print (testObj.testvar)

for some reason when I run the program it prints "test" but I am wanting it to print "None" or maybe even throw an error when I use

testobj.testvar = "test"
Dustin Nunyo
  • 96
  • 1
  • 9
  • 6
    You didn't define a setter. You're just overriding your property by setting it to `"test"`. If you want to define a setter, then you need to define a function decorated with `@testvar.setter`. And make sure your class [inherits from `object`](http://stackoverflow.com/questions/598077/why-does-foo-setter-in-python-not-work-for-me). – Vincent Savard May 09 '16 at 19:01
  • but even when I use ` @testvar.setter def testvar(self, value): assert False ` it does the same thing – Dustin Nunyo May 09 '16 at 19:04
  • 1
    Read the link I provided, you most likely didn't inherit `object`. – Vincent Savard May 09 '16 at 19:05
  • Aaah no it didn't lol I didn't realize I had to inherit from object...ty. :) I wish this was an actual answer I would mark it as the solution. lol – Dustin Nunyo May 09 '16 at 19:11
  • Just follow the link of the duplicate and upvote the accepted answer. :) – Vincent Savard May 09 '16 at 19:12

3 Answers3

0

You are dynamically creating a new member variable, called testvar, and adding it to your class, which then overrides your property name.

To verify this, you can change the assignment to e.g.

testObj.testvar2 = "test"

and everything will work as you expect, showing None as the value for testvar.

Matt Jordan
  • 2,133
  • 9
  • 10
  • ok but even when I use a `@testvar.setter` decorator it still does the same thing...I updated my op to show the changes I made – Dustin Nunyo May 09 '16 at 19:07
0

Add object as parent class.

class Testclass(object):
    def __init__(self):
        self._testvar = None

    @property
    def testvar(self):
        return self._testvar

    @testvar.setter
    def testvar(self, value):
        self._testvar = value

testObj = Testclass()
print(testObj.testvar)
testObj.testvar = "test"
print(testObj.testvar)

>>> None
>>> test
C14L
  • 12,153
  • 4
  • 39
  • 52
-1

I'm pretty sure that the way python works, when you do:

testobj.testvar = "test"

what you are actually doing is replacing the method Testclass.testvar() with the string "test". Essentially you are stomping on your function. Maybe you meant to do

testobj._testvar = "test"
Manetho
  • 147
  • 1
  • 3
  • Well, I am trying to avoid accessing the member variables directly outside of the class and instead using getters and setters so that I can access them safely. I always thought the @property decorator was used to turn a function into a getter method. – Dustin Nunyo May 09 '16 at 19:09
  • Calling it a getter doesn't prevent you from coming along later and replacing it, which is what you've done here. – Manetho May 09 '16 at 19:14