There are a couple of problems here:
__init__ is only run when you create an instance, e.g. obj = a(). This means that when you do a.func, the setattr() call hasn't happened
- You cannot access the attributes of a class directly from within methods of that class, so instead of using just
_func inside of __init__ you would need to use self._func or self.__class__._func
self will be an instance of a, if you set an attribute on the instance it will only be available for that instance, not for the class. So even after calling setattr(self, 'func', self._func), a.func will raise an AttributeError
- Using
staticmethod the way you are will not do anything, staticmethod will return a resulting function, it does not modify the argument. So instead you would want something like setattr(self, 'func', staticmethod(self._func)) (but taking into account the above comments, this still won't work)
So now the question is, what are you actually trying to do? If you really want to add an attribute to a class when initializing an instance, you could do something like the following:
class a():
def _func(self):
return "asdf"
def __init__(self, *args, **kwargs):
setattr(self.__class__, 'func', staticmethod(self._func))
if __name__ == '__main__':
obj = a()
a.func
a.func()
However, this is still kind of weird. Now you can access a.func and call it without any problems, but the self argument to a.func will always be the most recently created instance of a. I can't really think of any sane way to turn an instance method like _func() into a static method or class method of the class.
Since you are trying to dynamically add a function to the class, perhaps something like the following is closer to what you are actually trying to do?
class a():
pass
def _func():
return "asdf"
a.func = staticmethod(_func) # or setattr(a, 'func', staticmethod(_func))
if __name__ == '__main__':
a.func
a.func()