0

I can't set an attribute of a function inside of a class. Minimal example:

class Foo:
    def bar(self):
        pass

f = Foo()
f.bar.attribute = True 

For me, this throws an AttributeError: 'method' object has no attribute 'attribute' (setattr(f.bar, 'attribute', True) instead of the last line throws the same error).

Is there a more elegant or pythonic way to set the attribute than f.bar.__dict__['attribute'] = True?

1
  • You are defeating the whole purpose of class encapsulation if you want to modify a variable that is within the scope of a class method from outside that method. If you really need to control an attribute from outside, it should instead go as method parameter. You could have "attribute" as method parameter with default value (may be True is what you want). Commented Oct 12, 2018 at 23:12

2 Answers 2

4

Method objects don't have anywhere to store their own arbitrary attributes. Also, method objects are created on each access - f.bar is not f.bar - so even if you could set an attribute on a method object, it wouldn't be there when you tried to look for it again. This means that you really shouldn't try to set attributes on method objects.

When you ask for an attribute a method object doesn't recognize, it forwards the request to the underlying function, so f.bar.__dict__ is really Foo.bar.__dict__. Setting entries in that dict will set attributes on the underlying function, so they'll be visible through every instance of Foo, and methods of separate instances won't have independent attributes.

Whatever problem you were trying to solve by setting attributes on method objects, you should find some other way to solve it.

Sign up to request clarification or add additional context in comments.

Comments

1

I can't set an attribute of a function inside of a class.

Actually, you can. What you tried to do was set an attribute of the particular method off of an instance of the class. That, you can't do (AFAIK).

Foo is the class. Try Foo.bar.attribute = True. This will affect all instances of Foo, not just f. For example:

class Foo:
    def bar(self):
        pass

f = Foo()
Foo.bar.attribute = True
print(f.bar.attribute) # outputs True
z = Foo()
print(z.bar.attribute) # Also outputs True

In fact, f.bar.__dict__['attribute'] = True actually sets it at the class level as well:

class Foo:
    def bar(self):
        pass

f = Foo()
f.bar.__dict__['attribute'] = True
print(f.bar.attribute) # Outputs True                                                                                                                                                                       
z = Foo()
print(z.bar.attribute) # Also Outputs True 

Comments

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.