Is it possible to store method inside 'init'
Depends on what you mean by "storing" ? But if you meant "define", yes, you can define functions (nb: def always defines a function, it only becomes a "method" when it's looked up on a class or instance). And you don't need exec for this:
class Foo(object):
def __init__(self, arg):
def bar(baaz):
print("in bar: {}".format(baaz))
bar(arg)
and then to call it in other methods later?
If you want to make it a method, you can add it either to the instance:
class Foo(object):
def __init__(self, arg):
self.arg = arg
def bar(self):
print("in self.bar: {}".format(self.arg))
self.bar = bar.__get__(self, type(self))
or to the class (which means it will be overwritten every time you instanciate the class):
class Foo(object):
def __init__(self, arg):
self.arg = arg
def bar(self):
print("in self.bar: {}".format(self.arg))
type(self).bar = bar
If it's possible, is it a good practice to do or bad?
Well, as written above, it's absurd, confusing and inefficient, so I fail to see how this could qualify as good practice. And doing it with exec is just a complete WTF.
If the goal is to somehow parameterize a given method for each instance (based on a condition or whatnot), you can just pass the function - or any callable FWIW - as an argument (python functions are objects like any other):
class Foo(object):
def __init__(self, arg, strategy):
self.arg = arg
# we may not want to expose it
# as part of the class API
self._strategy = strategy
def bar(self, value):
return self._strategy(self, value)
def my_strategy(foo, value):
return foo.arg * value
f = Foo(42, my_strategy)
f.bar(2)
FWIW, this is known as the "strategy" design pattern.