2

To use the following:

class MyClass:
    def __init__(self):
        self.title = None
    @title.setter
    def title(self, title):
        print ('TITLE SETTER: %s' % title)
        self._title = title

NameError: name 'title' is not defined

What's wrong with the above code?

FI-Info
  • 635
  • 7
  • 16
  • 3
    I ... err ... have you _tried it_ various interpreters? – g.d.d.c Oct 12 '19 at 03:47
  • 2
    this is valid in neither. – juanpa.arrivillaga Oct 12 '19 at 03:50
  • Are you trying to use `@property` ? – JacobIRR Oct 12 '19 at 03:54
  • 1
    probably you should first create getter using `@property def title(self): return 'Hello World'`. And then you can use `@title` – furas Oct 12 '19 at 03:55
  • @furas that seems like it's the issue. – FI-Info Oct 12 '19 at 03:57
  • as for me it is not issue - if you want to use `@` then you would have to create getter which will create `@title`. If you what `setter` without `getter` then see [Python class @property: use setter but evade getter?](https://stackoverflow.com/questions/17576009/python-class-property-use-setter-but-evade-getter) – furas Oct 12 '19 at 04:00
  • @CalebGoodman The user has edited their question multiple times. Previously, Python2 and Python3 featured in the question. You can check the revisions of this post [here](https://stackoverflow.com/posts/58350677/revisions). – Ross Jacobs Oct 12 '19 at 04:12

1 Answers1

3

The name title won't exist in the body of the class until you first create it. The fact is that what allows getters and setters to exist in this way in Python is the descriptor protocol - with a helper callable named property{ . Back in the old times (circa Python 2.4), it was found out that if property taking a single argument would return apropertyobject with a.setter` attribute, this attribute could be used as a decorator to register the setter method for the same object.

Prior to that one had to declare the getter, setter and deleter as ordinary methods, and create the property object with a line like title = property(title_getter, title_setter, tittle_deleter) in the class body.

Thus, if you do:

class MyClass:
    def __init__(self):
        self.title = None

    @property
    def title(self):
        return self._title

    @title.setter
    def title(self, title):
        print 'TITLE SETTER: %s' % title
        self._title = title

your code will work, because property is called with the function title as a parameter - it then returns a property object, which have a __get__ method that will cause that original title function to be called, and a setter and deleter attributes, which are callables - the title.setter when used as a decorator, just add it internally to the property object, so that its __set__ method will cause it to be invoked. (The working of the descriptor protocol and the __set__, __delete__ and __get__ methods, used internally by property is described in the language Data Model document)

jsbueno
  • 99,910
  • 10
  • 151
  • 209
  • is `@property` the same thing as doing `@title.getter`? – FI-Info Oct 12 '19 at 04:02
  • 1
    No . The language does not "guess" you will try to create a property with the name "title" - it is declaring the function, and having it decorated with "property" that makes the object "property" with the name "title" exist from that point on. – jsbueno Oct 12 '19 at 04:10