Python: How to call an instance method from a class method of the same class
Question:
I have a class as follows:
class MyClass(object):
int = None
def __init__(self, *args, **kwargs):
for k, v in kwargs.iteritems():
setattr(self, k, v)
def get_params(self):
return {'int': random.randint(0, 10)}
@classmethod
def new(cls):
params = cls.get_params()
return cls(**params)
and I would like to be able to do:
>>> obj = MyClass.new()
>>> obj.int # must be defined
9
I mean without creating a new instance of MyClass
, but obviously it’s not that simple, because calling MyClass.new()
throws TypeError: unbound method get_params() must be called with MyClass instance as first argument (got nothing instead)
Is there any way to accomplish so?
Thanks.
Answers:
No, you can’t and shouldn’t call an instance method from a class without an instance. This would be very bad. You can, however call, a class method from and instance method. Options are
- make
get_param
a class method and fix references to it
- have
__init__
call get_param
, since it is a instance method
Also you may be interested in an AttrDict since that looks like what you are trying to do.
You can call instance method with classmethod when treating it like instance method and add class as instance. IMO it is really bad practice, but it solves your problem.
@classmethod
def new(cls):
params = cls.get_params(cls)
return cls(**params)
You need to pass cls
to an instance method from a class method as shown below to call the instance method from the class method:
class Person:
def test1(self):
print("Test1")
@classmethod
def test2(cls):
cls.test1(cls) # Needed to pass "cls"
obj = Person()
obj.test2()
Output:
Test1
I have a class as follows:
class MyClass(object):
int = None
def __init__(self, *args, **kwargs):
for k, v in kwargs.iteritems():
setattr(self, k, v)
def get_params(self):
return {'int': random.randint(0, 10)}
@classmethod
def new(cls):
params = cls.get_params()
return cls(**params)
and I would like to be able to do:
>>> obj = MyClass.new()
>>> obj.int # must be defined
9
I mean without creating a new instance of MyClass
, but obviously it’s not that simple, because calling MyClass.new()
throws TypeError: unbound method get_params() must be called with MyClass instance as first argument (got nothing instead)
Is there any way to accomplish so?
Thanks.
No, you can’t and shouldn’t call an instance method from a class without an instance. This would be very bad. You can, however call, a class method from and instance method. Options are
- make
get_param
a class method and fix references to it - have
__init__
callget_param
, since it is a instance method
Also you may be interested in an AttrDict since that looks like what you are trying to do.
You can call instance method with classmethod when treating it like instance method and add class as instance. IMO it is really bad practice, but it solves your problem.
@classmethod
def new(cls):
params = cls.get_params(cls)
return cls(**params)
You need to pass cls
to an instance method from a class method as shown below to call the instance method from the class method:
class Person:
def test1(self):
print("Test1")
@classmethod
def test2(cls):
cls.test1(cls) # Needed to pass "cls"
obj = Person()
obj.test2()
Output:
Test1