Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a method attribute in a class

Tags:

python

I can create a function of the following format.

def bar():
    if not hasattr(bar, 'c'):
        bar.c = 0
    bar.c += 1
    return bar.c

When run it produces the following output, as intended:

>>> bar()
1
>>> bar()
2
>>> bar()
3

But if I suddenly move this function to a class, Python gives me an error.

class Foo(object):

    def bar(self):
        if not hasattr(self.bar, 'c'):
            self.bar.c = 0
        self.bar.c += 1
        return self.bar.c

Now I get

>>> foo = Foo()
>>> foo.bar()
...
AttributeError: 'method' object has no attribute 'c'

It's telling me it has no attribute, but I'm trying to create the attribute. What's going on here?

like image 568
zephyr Avatar asked Mar 13 '16 03:03

zephyr


Video Answer


1 Answers

Taken from the python documentation (https://docs.python.org/2/library/stdtypes.html?highlight=instancemethod) "However, since method attributes are actually stored on the underlying function object (meth.im_func), setting method attributes on either bound or unbound methods is disallowed."

In other words, we could have tried Foo.bar.im_func.c = 0, but unfortunately, it is read-only, so it doesn't work.

Therefore, for what you try to accomplish, I would suggest

class Foo(object):
  c = 0
  def bar(self):
    Foo.c += 1
    return Foo.c

f = Foo()
print f.bar()
print f.bar()
print f.bar()

Works on python2 and python3.

The only "drawback" is that c would be available to any other method of class Foo.

like image 52
Sci Prog Avatar answered Sep 28 '22 11:09

Sci Prog