0

我有一个继承自 ndb.Model 的对象(一个 Google App Engine 事物)。此对象有一个名为 commentid 的属性:

class Comment(ndb.Model):
   commentid = ndb.StringProperty()

看了一堆文章,都说这是实现一个属性的方式:

@property
def commentid(self):
   if not self._commentid:
       self._commentid = "1"
   return self._commentid

但我收到一条错误消息Comment object has no attribute _commentid。我究竟做错了什么?

编辑:好的,显然我在这里有点困惑。我来自 Objective-C,如果你有一个属性被调用,x那么你会自动获得一个_x在你的 getter 和 setter 中调用的变量。所以我认为这也是 Python 中发生的事情。但显然我需要手动为带有下划线前缀的变量设置一个值。

我想要的只是实现一个getter,我在返回之前对值进行一些检查。我该怎么做?

4

2 回答 2

5

实现这样的属性需要您为对象定义属性。您在那里所做的是定义一个名为 Comment 的类,但您没有为它的对象定义任何属性,而是为类本身定义它们。

让我用一个小例子来演示:

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"

在上面的例子中,我定义了 classExampleClass并给它一个name带有 value的变量Example Object。之后,我创建了一个 object a = ExampleClass(),但是它没有获得 name 属性,因为该属性是为类本身定义的,而不是为它的对象定义的。

要解决此问题,您在__init__-method 中定义名称,每当创建该类的对象时都会调用该名称。

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

在那里我ExampleClass再次定义了,但我也__init__为它定义了方法。Init 方法只接受一个参数,self,该参数将自动传递给函数。它是正在创建的对象。然后我设置self.name = "Example Class",因为 self 是对象本身,我们设置对象的属性name

创建属性

要为您的属性实现 setter 和 getter,请添加以下内容:

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

此外,您还应该编辑__init__方法以name作为参数。

def __init__(self, name="Example Object"):
    self.name = name
于 2012-11-22T18:57:43.513 回答
2

如果您self._commentid直接访问,则需要对其进行定义,否则会引发异常。由于您改为检查是否_commentid已定义(给它一个默认值),我会使用hasattr

@property
def commentid(self):
   if not hasattr(self, "_commentid"):
       self._commentid = "1"
   return self._commentid
于 2012-11-22T18:51:45.987 回答