9

Python (2.6) 似乎是无缘无故的,任何人都可以看到这段代码有问题吗?

class DB ():
    def doSomething (self, str):
        print str

class A ():
    __db = DB()

    @staticmethod
    def getDB ():
        return A.__db

    db = property(getDB)


A.db.doSomething("blah")

失败,但有以下例外:

AttributeError:“属性”对象没有属性“doSomething”

我的理解是一个属性在访问时会自动运行它的getter,那么为什么它会抱怨一个属性对象,为什么它没有找到我明确可用的方法?

4

3 回答 3

19

除了需要从 继承之外object,属性仅适用于实例。

a = A()
a.db.doSomething("blah")

要使属性在类上起作用,您可以定义一个元类。(类是元类的一个实例,因此在元类上定义的属性对类起作用,就像在类上定义的属性对该类的实例起作用一样。)

于 2012-12-13T19:45:46.267 回答
1

您没有正确使用类。一个类(通常)是两件事:

  1. 用于创建一系列相关对象的工厂
  2. 这些对象的共同行为的定义

这些相关的对象是类的实例。普通方法是在类的实例上调用的,而不是在类本身上。如果您想要可以从类中调用的方法,而不需要实例,则需要用@classmethod(或@staticmethod)标记这些方法。

但是,我实际上并不知道从类对象中检索属性是否有效。我现在不能检查,但我不这么认为。您得到的错误A.db是检索定义属性本身的属性对象,而不是“评估”要获取的属性A.__db。属性对象没有doSomething属性。属性被设计为在类中创建,作为对这些类的实例如何工作的描述。

如果您确实打算使用 A 的实例,那么您需要创建一个:

my_a = A()
my_a.db.doSomething("blah")

但是,这也会失败。你没有正确地写成getDB任何一种方法。普通方法需要一个参数来表示它被调用的实例(传统上称为self):

def getDB(self):
    ...

静态方法不需要,但需要一个装饰器将它们标记为静态:

@staticmethod
def getDB():
    ...

类方法既需要一个参数来接收调用它们的类,还需要一个装饰器:

@classmethod
def getDB(cls):
    ...
于 2012-12-13T20:16:16.740 回答
-1

Python 中不需要 getter:

class B(object):
    def do_something(self, str):
        print str

class A(object):
    db = B()

A.db.do_something("blah")

(我也 PEP8:ed 代码)

于 2012-12-13T19:52:37.037 回答