Reputation: 32071
I have an object which inherits from ndb.Model (a Google App Engine thing). This object has a property called commentid:
class Comment(ndb.Model):
commentid = ndb.StringProperty()
Reading a bunch of articles, they all say this is the way to implement a property:
@property
def commentid(self):
if not self._commentid:
self._commentid = "1"
return self._commentid
but I get an error saying Comment object has no attribute _commentid
. What am I doing wrong?
Edit: Ok obviously I'm a bit confused here. I come from Objective-C, where if you have a property called x
then you automatically get a variable called _x
in your getters and setters. So I thought this is what was happening here in Python too. But apparently I need to manually set a value for the variable with an underscore prefix.
All I want is to implement a getter where I do some checking of the value before returning it. How would I do this?
Upvotes: 0
Views: 338
Reputation:
Implementing a property like that requires you to define the attribute for your object. What you're doing there, is defining a class called Comment but you don't define any attributes for it's objects, you define them for the class itself.
Let me demonstrate with a small example:
class ExampleClass:
name = "Example Object"
a = ExampleClass() # Init new instance of ExampleClass
print(a.name) # a doesn't own an attribute called "name"
print(ExampleClass.name) # --> "Example Object"
In the above example, I define class ExampleClass
and give it a variable name
with a value Example Object
. After that, I create an object a = ExampleClass()
, however it does not get the name attribute, cause the attribute is defined for the class itself, not for it's objects.
To fix this problem, you define the name inside __init__
-method, which gets called whenever an object of that class is created.
class ExampleClass:
def __init__(self):
self.name = "Example Class"
a = ExampleClass() # Init new instance of ExampleClass
print(a.name) # --> "Example Class"
print(ExampleClass.name) # --> ERROR: Exampleclass.name doesn't exist
There I define the ExampleClass
again, but I also define __init__
method for it. Init method takes only one parameter, self
, which will be automatically given to the function. It's the object which is being created. Then I set self.name = "Example Class"
, and since self is the object itself, we set the object's attribute name
.
To implement setter and getter for your attribute, you add the following:
class ExampleClass:
def __init__(self):
self.name = "Example Class"
@property
def name(self):
if not self._name:
pass #blabla code here
return self._name
@name.setter
def name(self, value):
#blabla more code
self._name = value
Also, you should edit the __init__
method to take name
as a parameter too.
def __init__(self, name="Example Object"):
self.name = name
Upvotes: 5
Reputation:
If you access self._commentid
directly, it needs to be defined or it'll raise an exception. Since you're instead checking if _commentid
is defined at all (to give it a default value), I'd use hasattr
:
@property
def commentid(self):
if not hasattr(self, "_commentid"):
self._commentid = "1"
return self._commentid
Upvotes: 2