3

I'd like to do something like this:

class Foo:
    def test(self, arg):
        self.test.x = 'prop x with ' + arg
        print "test!"

f = Foo()
f.test('bar')
print f.test.x

And get as an output something like this:

test!
prop x with bar

But instead I get an AttributeError: 'instancemethod' object has no attribute 'x'

By the way I can do such thing with function:

def test(arg):
    test.x = 'prop x ' + arg
    print "test!"

test('bar')
print test.x

which works just fine.

2
  • 3
    Not sure why you'd want to do this. Why not just add an attribute to the instance directly, rather than the method? Commented Feb 29, 2016 at 15:23
  • I am dynamically calling another methods from method and I'd like to save some information to an attribute of function, but I do not feel like using another classes, just to keep things simple. Commented Feb 29, 2016 at 15:25

4 Answers 4

2

You can't do this; and even if you could, methods are properties of the class, not the instance, so the same value would be set for all all instances of Foo.

Instead you should simply assign directly to the instance. You can add whatever attributes you like.

class Foo:
    def test(self, arg):
        self._x = 'prop x with ' + arg
Sign up to request clarification or add additional context in comments.

Comments

2

Even if you succeeded in setting the attribute, it wouldn't be preserved. In CPython, bound methods are created on the fly when you access them:

>>> class Foo:
...   def test(self, arg): pass
... 
>>> f = Foo()
>>> f.test is f.test
False

Comments

1

You can add members to a class instance, but not to a method.

class Foo:
  def test(self, arg):
    self.x = 'prop x with ' + arg
    print "test!"

f = Foo()
f.test('bar')
print f.x

Comments

1

We can arrive/achieve what you are looking for by litle tweaking

from collections import namedtuple

T = namedtuple('T', ['x'])

class Foo:
    def test(self, arg):
        self.test = T('prop x with ' + arg)
        print "test!"

f = Foo()
f.test('bar')
print f.test.x

Output will be:

test!
prop x with bar

Note

Reason I called it a tweak is, from this point, f.test is no more a callable.

2 Comments

But then f.test is no longer callable
That is the reason I called it a tweak :) Let me add that as note to my answer that once we do this, f.test is no more a callable

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.