Reputation: 736
I have a case, where I have an instance of a class in python which holds instances of other classes. For my use case, I would like a way to use the methods of the "inner" classes from the outer class without referencing the attribute holding the inner class.
I have made a simplistic example here:
class A:
def __init__(self):
pass
def say_hi(self):
print("Hi")
def say_goodbye(self):
print("Goodbye")
class C:
def __init__(self, other_instance):
self.other_instance= other_instance
def say_good_night(self):
print("Good night")
my_a = A()
my_c = C(other_instance=my_a)
# How to make this possible:
my_c.say_hi()
# Instead of
my_c.other_instance.say_hi()
Class inheritance is not possible, as the object passed to C may be an instance of a range of classes. Is this possible in Python?
Upvotes: 1
Views: 95
Reputation: 16486
I think this is the simplest solution although it is possible with metaprogramming.
class A:
def __init__(self):
pass
def say_hi(self):
print("Hi")
def say_goodbye(self):
print("Goodbye")
class C:
def __init__(self, other_class):
self.other_class = other_class
C._add_methods(other_class)
def say_good_night(self):
print("Good night")
@classmethod
def _add_methods(cls, obj):
type_ = type(obj)
for k, v in type_.__dict__.items():
if not k.startswith('__'):
setattr(cls, k, v)
my_a = A()
my_c = C(other_class=my_a)
my_c.say_hi()
output :
Hi
First we get the type of passed instance, then we iterate through it's attribute (because methods are attributes of the class not the instance).
If self.other_class
is only needed for this purpose, you can omit it as well.
Upvotes: 2
Reputation: 452
So, because you have done:
my_a = A()
and my_c = C(other_class=my_a)
.
my_c.other_class
is the same as my_a
asthey point to the same location in memory.
Therefore, as you can do my_a.say_hi()
you could also do my_c.other_class.say_hi()
.
Also, just a note, as you are calling A()
before you store it into other_classes
, I would probably rename the variable other_classes
to class_instances
.
Personally, I think that would make more sense, as each of those classes would have already been instantiated.
Upvotes: 0