Python AttributeError: 'property' 对象没有属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13867172/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 09:47:28  来源:igfitidea点击:

AttributeError: 'property' object has no attribute

pythonclassexceptionobjectproperties

提问by Ben

Python (2.6) seems to be derping for no reason, can anyone see a problem with this code?

Python (2.6) 似乎无缘无故地进行了 derping,有人能看出这段代码有问题吗?

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,那么为什么它会抱怨一个属性对象,为什么它没有找到我明确可用的方法?

采纳答案by kindall

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.)

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

回答by Lennart Regebro

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:编辑了代码)

回答by Ben

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
  1. 用于创建相关对象系列的工厂
  2. 这些对象的共同行为的定义

These related objects are the instancesof the class. Normal methods are invoked on instancesof 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.dbis retrieving the property object which defines the property itself, it isn't "evaluating" the property to get A.__db. Property objects have no doSomethingattribute. Properties are designed to be created in classes as descriptions of how the instancesof those classes work.

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

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 getDBas any kind of method. Normal methods need an argument to represent the instance it was invoked on (traditionally called self):

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