简体   繁体   中英

Setting Attribute Of python Method In Class

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 ?

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.

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 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM