Python (2.6) seems to be derping for no reason, can anyone see a problem with this code?
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'
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?
The property() method in Python provides an interface to instance attributes. It encapsulates instance attributes and provides a property, same as Java and C#. The property() method takes the get, set and delete methods as arguments and returns an object of the property class.
Use Python's dir to Print an Object's Attributes One of the easiest ways to access a Python object's attributes is the dir() function. This function is built-in directly into Python, so there's no need to import any libraries.
The following example shows how to create a Circle class with a handy property to manage its radius: # circle.py class Circle: def __init__(self, radius): self. _radius = radius def _get_radius(self): print("Get radius") return self. _radius def _set_radius(self, value): print("Set radius") self.
In addition to needing to inherit from object
, properties only work on instances.
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:
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
).
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
. Property objects have no doSomething
attribute. 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:
my_a = A()
my_a.db.doSomething("blah")
However, this will also fail. You have not correctly written getDB
as any kind of method. Normal methods need an argument to represent the instance it was invoked on (traditionally called 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):
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With