Python Forum

Full Version: How can you add an attribute to a function within a class?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi,

I'm trying to add an attribute to a function / method within a class and then change it from within the function.
Couldn't figure out how to do this, while similar approach to a function not in a class works.

Simplified example:

Ok to add attribute to function like this:

def cb0():
    self.cb0.data=2
cb0.data=4
But fails when adding attribute to function within class like this:

class cam():
    def cb1(self):
        print(self.cb1.data)  #--> strangely, this line runs and reads .data
        self.cb1.data=2  #-->  but this line gives an error, stating there is no object 'data'
    cb1.data=4
a=cam()
a.cb1()
AttributeError: 'method' object has no attribute 'data'
this statement: cb0.data=4
is not part of cb0()
in your class, cb1 is not a method, and therefore cannot be called
Please don't use single letter names, it does nothing to give a hint as to what the code is about.
Writing meaningful names, even when just a homework assignment, will help you write better code as you advance.

moved to homework
Maybe I am missing something...Tell me if I do. But this is really tricky question.
I would recommend to read related pep first (PEP232).

You can set and get function attributes in Python.
def func():
    func.data = 2
    print(func.data)

func.data=4
func()  # this overrides func.data and set it to 2
Output:
2
Note, the type of func is function:
type(func)
Output:
<class 'function'>
If you have a class:

class MyClass:
    def custom_method(self):
        pass
    custom_method.data = 10
"functions" defined within the class's body almost the same as regular functions (like func above)
type(MyClass.custom_method)
Output:
<class 'function'>
However, there is a difference (At least in Python 2 they are called unbound methods),
they become bounded when accessed from class's instances.
obj = MyClass()
type(obj.custom_method)
Output:
<class 'method'>
In Python 2 they were called bounded methods.
As mentioned above PEP says that it is prohibited to assign attributes to bounded methods
(there are issues with this, see the PEP-232 for details).
However, you can do this in a hacky way:
class MyClass:
    def custom_method(self):
       print("Old value: ", self.custom_method.data)
       self.custom_method.__func__.data = 'New data'   # .__func__ links to "unbound" method, as it is a regular function
       print("New value: ", self.custom_method.data)
    custom_method.data = 'Old data'

c = MyClass()
c.custom_method()
Output:
Old value: Old data New value: New data
This is for educational purposes only. Don't follow this hacky way.