Python property returning property object

Question:

I have a class like this:

class Foo(object):
    def __init__(self):
        self.bar = property(self.get_bar)

    def get_bar(self):
        return "bar"

print Foo().bar  #this prints <property object at 0x0051CB40>

I’ve seen How do Python properties work?, How to set a python property in __init__, but they all use the decorator method, which i don’t because i want a different name. And I need access to self

How do i get the property to behave?

Asked By: gcq

||

Answers:

You can do it like this

class Foo(object):
    def __init__(self):
        self.__bar = None

    def get_bar(self):
        return self.__bar

    def set_bar(self, value):
        self.__bar = value

    bar = property(get_bar, set_bar)

foo = Foo()
print foo.bar    # None
foo.bar = 1
print foo.bar    # 1
Answered By: thefourtheye

You need to make a minor change:

class Foo(object):

    def get_bar(self):
        return "bar"

    bar = property(get_bar)

print Foo().bar # prints bar

The property needs to be an attribute of the class, not the instance; that’s how the descriptor protocol works.

Answered By: jonrsharpe

You can also do it like shown here:

class Foo(object):
    def __init__(self):
        self._bar = None

    @property
    def bar(self):
        return self._bar

    @bar.setter
    def bar(self, value):
        self._bar = value

    @bar.deleter
    def bar(self):
        self._bar = None # for instance

which is equivalent to:

class Also_Foo(object):
    def __init__(self):
        self._bar = None

    def get_bar(self):
        return self._bar

    def set_bar(self, value):
        self._bar = value

    def del_bar(self):
        self._bar = None # for instance

    bar = property(fget=get_bar, fset=set_bar, fdel=del_bar, doc=None)

BUT without polluting the class namespace with get and set methods for each attribute.

You retain external direct access to the variable by using ._bar instead of .bar.

Answered By: berna1111

The object is not instantiated.

class Foo(object):
  def get_bar(self):
    return "bar"

bar = Foo()
print(bar.get_bar)
Answered By: warchitect

My use case required defining bar as a property only under certain conditions, so I took jonrsharpe‘s advice and moved the definition into __new__ instead:

class Foo(object):
    def __new__(cls):
        cls.bar = property(cls.get_bar)
        return super(Foo, cls).__new__(cls)

    def get_bar(self):
        return "bar"

print(Foo().bar)  #this prints "bar"

However, nothing was gained by this "cleverness". Once the condition was met, the class contained the property. I might as well have defined it as jonrsharpe did.

Answered By: jcomeau_ictx

Do the following if you want to do within init()

class Foo(object):
    def __init__(self):
        type(self).bar = property(self.get_bar)

    def get_bar(self):
       return "bar"
Answered By: Bora Inceler
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.