2012-11-22 71 views
0

我从ndb.Model(谷歌的App Engine的东西)继承的对象。这个对象有一个属性叫做commentid:Python的财产不工作

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的属性,那么你会在你的getter和setters中自动获得一个叫做_x的变量。所以我认为这也是Python在这里发生的事情。但显然我需要为带有下划线前缀的变量手动设置一个值。

所有我想要的是实现一个getter,我返回之前做的价值的一些检查。我将如何做到这一点?

+0

您提到authorID只是一次,它不会再出现。 –

+0

@PaulC应该是纪念 – Snowman

+0

这是你的全班上课吗? – Michael0x2a

回答

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" 

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

若要解决此问题,您可以在__init__ - 方法中定义名称,只要该类的对象被创建,该方法就会被调用。

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__方法。初始化方法只需要一个参数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 
+0

等待,如果您尚未在init方法中手动指定它,您如何访问self._name? – Snowman

+0

我正在专门讨论下划线前缀变量.. – Snowman

+0

您在init中调用'self.name =“示例类”',它将自动使用参数“Example Class”调用'@ name.setter'函数,并且在setter中我们设置'self._name =“示例类”'。您可以更改init来设置'self._name'而不是'self.name',这取决于您是要调用setter还是仅设置变量。 – 2012-11-22 19:08:42

2

如果你直接访问self._commentid,它需要被定义或者它会引发异常。既然你不是检查,如果_commentid在所有定义的(给它一个默认值),我会使用hasattr

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

因此Python不会自动给你一个带有属性的_varName? – Snowman

+0

@mohabitar:不,您可以在班级中将None分配给它,以使这更容易。 –