简体   繁体   English

AttributeError:'property'对象没有属性

[英]AttributeError: 'property' object has no attribute

Python (2.6) seems to be derping for no reason, can anyone see a problem with this code? 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")

Fails with the exception: 失败,例外情况:

AttributeError: 'property' object has no attribute 'doSomething' AttributeError:'property'对象没有属性'doSomething'

It was my understanding that a property would automatically run its getter when accessed, so why is it complaining about a property object, and why isn't it finding my clearly available method? 我的理解是,一个属性在访问时会自动运行它的getter,那么为什么它会抱怨一个属性对象,为什么它找不到我明显可用的方法呢?

In addition to needing to inherit from object , properties only work on instances. 除了需要从object继承之外,属性仅适用于实例。

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

To make a property work on the class, you can define a metaclass. 要使属性在类上运行,可以定义元类。 (A class is an instance of a metaclass, so properties defined on the metaclass work on the class, just as properties defined on a class work on an instance of that class.) (类是元类的实例,因此在元类上定义的属性在类上工作,就像在类上定义的属性在该类的实例上工作一样。)

You aren't using classes correctly. 您没有正确使用类。 A class is (normally) two things: 一类是(通常)两件事:

  1. A factory for creating a family of related objects 用于创建相关对象族的工厂
  2. A definition of the common behaviour of those objects 这些对象的共同行为的定义

These related objects are the instances of the class. 这些相关对象是类的实例 Normal methods are invoked on instances of the class, not on the class itself. 在类的实例上调用普通方法,而不是在类本身上调用。 If you want methods that can be invoked from the class, without an instance, you need to label the methods with @classmethod (or @staticmethod ). 如果您想要从类中调用的方法,而不需要实例,则需要使用@classmethod (或@staticmethod )标记方法。

However I don't actually know whether properties work when retrieved from a class object. 但是我实际上并不知道从类对象中检索属性是否有效。 I can't check right now, but I don't think so. 我现在无法检查,但我不这么认为。 The error you are getting is that A.db is retrieving the property object which defines the property itself, it isn't "evaluating" the property to get A.__db . 您得到的错误是A.db正在检索定义属性本身的属性对象,它不是“评估”该属性以获得A.__db Property objects have no doSomething attribute. 属性对象没有doSomething属性。 Properties are designed to be created in classes as descriptions of how the instances of those classes work. 属性设计为在类中创建,作为这些类的实例如何工作的描述。

If you did intend to be working with an instance of A, then you'll need to create one: 如果你打算使用A的实例,那么你需要创建一个:

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

However, this will also fail. 但是,这也会失败。 You have not correctly written getDB as any kind of method. 您没有正确编写getDB作为任何一种方法。 Normal methods need an argument to represent the instance it was invoked on (traditionally called self ): 普通方法需要一个参数来表示它被调用的实例(传统上称为self ):

def getDB(self):
    ...

Static methods don't, but need a decorator to label them as static: 静态方法没有,但需要装饰器将它们标记为静态:

@staticmethod
def getDB():
    ...

Class methods need both an argument to receive the class they were invoked on, and a decorator: 类方法需要一个参数来接收它们被调用的类,以及一个装饰器:

@classmethod
def getDB(cls):
    ...

You don't need getters in Python: 你不需要Python中的getter:

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

class A(object):
    db = B()

A.db.do_something("blah")

(I also PEP8:ed the code) (我也是PEP8:ed代码)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM