Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error "'str' object is not callable" when using property setter

I am trying to use a property setter as below. I'm following the example here: How does the @property decorator work?

class Contact:
    def __init__(self):
        self._funds = 0.00

    @property
    def funds(self):
        return self._funds

    @funds.setter
    def funds(self, value):
        self._funds = value

The getter works fine

>>> contact = Contact()
>>> contact.funds
0.0

but I'm missing something about the setter:

>>> contact.funds(1000.21)

Traceback (most recent call last):
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/doctest.py", line 1315, in __run
    compileflags, 1) in test.globs
  File "<doctest __main__.Contact[2]>", line 1, in <module>
    contact.funds(1000.21)
TypeError: 'str' object is not callable

What am I doing wrong here?

like image 934
Mark Irvine Avatar asked Jun 26 '18 16:06

Mark Irvine


People also ask

How do I fix str object is not callable?

The result was the TypeError: 'str' object is not callable error. This is happening because we are using a variable name that the compiler already recognizes as something different. To fix this, you can rename the variable to a something that isn't a predefined keyword in Python. Now the code works perfectly.

What does it mean when it says STR object is not callable?

The Python "TypeError: 'str' object is not callable" occurs when we try to call a string as a function, e.g. by overriding the built-in str() function. To solve the error, make sure you're not overriding str and resolve any clashes between function and variable names.

What does it mean that something is not callable?

Definition of noncallable : not callable specifically : not subject to a demand for presentation for payment noncallable debts.

Are strings callable?

The Problem: typeerror: 'str' object is not callable When you try to call a string like you would a function, an error is returned. This is because strings are not functions. To call a function, you add () to the end of a function name.


2 Answers

Just use the contact.funds = 1000.21 syntax. It will set it using @funds.setter.

I cannot reproduce your 'str' object is not callable error, rather I get a 'float' object is not callable error. More detail on how it is being run would be helpful for diagnosing that. Regardless, the reason is that contact.funds will give you back the value of contact._funds, which is not a callable object, hence the error.

like image 176
MoxieBall Avatar answered Sep 16 '22 14:09

MoxieBall


@MoxieBall and @pavan have already shown the syntax. I'll dive in a bit deeper to help explain what's going on.

The @property decorator exists precisely so you can get and set object fields via the convenient x = object.field and object.field = value syntax. So @MarkIrvine, you've done everything correctly to enable your contact.funds() getter to become contact.funds and your contact.funds(value) setter to become contact.funds = value.

The confusion lies in the fact that the @property decorator re-defines the symbols in your contact objects. In other words, contact.funds is a Descriptor object. Once you've applied the @funds.setter decorator to def funds(self, value):, the funds function no longer exists as you defined it. So contact.funds(value) first returns the contact.funds property, then tries to call it as if it were a function.

Hope that helps. =)

like image 21
tankthinks Avatar answered Sep 19 '22 14:09

tankthinks