How to contain an object and call its method in a class? - python

I have two classes (ClassA and ClassB) and ClassA contains one object, b, that is an instance of ClassB. The question is that I can't call the b's method in Class A.
class ClassB(object):
def __init__(self):
print('Class B init ...')
def show(self):
print('Showing class b')
class ClassA(object):
#__classb = ClassB()
def __init__(self, classb):
print('Class A init ...')
__classb = classb
def show(self):
__classb.show() # <=== I just want to do this!
b = ClassB()
a = ClassA(b)
a.show()
I expect the result should be:
Class B init ...
Class A init ...
Showing class b
But I meet the problem as this image shows:
How can I fix it?

By doing __classb = classb you are only defining a local __classb variable in the __init__ method.
If you want __classb to be an instance attribute you will need to use self:
self.__classb = classb
And then:
def show(self):
self.__classb.show()

You should create a attribute for a instance of class B in class A like that self.__classb.
Following code
class ClassB(object):
def __init__(self):
print('Class B init ...')
def show(self):
print('Showing class b')
class ClassA(object):
def __init__(self, classb):
print('Class A init ...')
self.__classb = classb
def show(self):
self.__classb.show() # <=== I just want to do this!
b = ClassB()
a = ClassA(b)
a.show()

Related

Share attributes/ variables between classes python

class Base(object):
def __init__(self):
print("Base created")
a = "baseclass"
class ChildA(Base):
def __init__(self):
Base.__init__(self)
b = "child a"
class ChildB(Base):
def __init__(self):
super(ChildB, self).__init__()
c = "child b"
print(a)
print(b)
ChildA()
ChildB()
NameError: name 'a' is not defined
Your issue here is that you're trying to access local variables instead of instance attributes.
Here's how you should do it:
class Base():
def __init__(self):
print("Base created")
# Note that you should use `self.a` instead of `a`
self.a = "baseclass"
class ChildA(Base):
def __init__(self):
Base.__init__(self)
# Use `self.b` instead of `b`
self.b = "child a"
# Did you forget to inherit from `ChildA`?
class ChildB(ChildA):
def __init__(self):
# The `super()` call can be simplified
super().__init__()
# Use `self.c` instead of `c'
self.c = "child b"
# Access the instance variables using `self.`
print(self.c)
print(self.b)
print(self.a)
ChildA()
ChildB()
From the console output:
Base created
Base created
child b
child a
baseclass

python instantiate child instance from parent object

I have an object which is instantiated from parent class(it will b variable at below example code)
and i want to use this object like a child class instance without knowledge about the member variable of parent class
is there any recommendation?
class A:
def __init__(self):
pass # some member variables are assigned
pass
class B(A):
def test(self):
print("test")
pass
b = A()
b.test() # error
You can do this by setting __class__ of b to B. But read this first:
https://stackoverflow.com/a/13280789/6759844
class A:
def __init__(self):
pass # some member variables are assigned
pass
class B(A):
def test(self):
print("test")
pass
b = A()
b.__class__ = B
b.test() # error

Python: pass whole self of class to init of new class

I have a class and a sub-class, I'd like to pass the whole of the self of the class to the sub-class. I can pass self over to the new class explicitly easily enough, e.g.
class foo:
def __init__(self, a, b):
self.a = a
self.b = b
self.c = 'foo'
def foo_method(self):
print('a foo method')
class bar(foo):
def __init__(self, foo_object):
self.a = foo_object.a
self.b = foo_object.b
self.c = foo_object.c
def bar_method(self):
print('a bar method')
foo_object = foo(a = 'a', b = 'b')
bar_object = bar(foo_object)
bar_object.a
Is there a more succinct way to pass these over? Something like:
class bar(foo):
def __init__(self, foo_object):
self = self.foo_object
Update:
Thanks https://stackoverflow.com/users/10104112/bastien-antoine, the following solution worked:
class bar(foo):
def __init__(self, foo_object):
self.__dict__ = foo_object.__dict__.copy()
def bar_method(self):
print('a bar method with ' + str(self.c))
Have you tried the copy builtins library?
Otherwise I think you can easily implement your own .copy() method that would copy the values from the old object __dict__ to the new one. Something like this:
class MyObject:
a = None
def set_default_values(self):
self.a = 1
def copy(self, old):
if type(self) == type(old):
self.__dict__ = old.__dict__.copy()
else:
raise TypeError('Wrong type')
if __name__ == "__main__":
obj_1 = MyObject()
print(obj_1.a)
obj_1.set_default_values()
print(obj_1.a)
obj_2 = MyObject()
print(obj_2.a)
obj_2.copy(obj_1)
print(obj_2.a)
Note that I've added a type checking to be sure that you copy attributes that would exist otherwise, but I think simply self.__dict__ = old.__dict__.copy() would work fine, thought you might end up with attributes you might not suppose to have in the new object.
Hope this helps!
I think that you can do that with
class bar(foo):
def __init__(self):
super(bar, self).__init__()
with this code, you ran the init function for the subclass

inheritance using parent class method without calling parent class

Is there any way to access parent class method, without actually calling the class?
e.g.:
1)
class A():
def __init__(self):
print('A class')
def name():
print('name from A class')
2)
class B(A):
# I want to make use of name without actually calling or running A.
# Is there any way to do that?
Yeah, you can just call it directly. This works fine:
class A():
def __init__(self):
print('A class')
def name(self):
print('name from A class')
class B(A):
pass
B().name()
> A class
> name from A class
You can also use it inside of the class, like
class B(A):
def b_name(self):
print('I am B!')
self.name()
If what you're trying to get around is calling A's init, then maybe you should turn name into a classmethod:
class A():
def __init__(self):
print('A class')
#classmethod
def name(self):
print('name from A class')
A.name()
> name from A class
Alternatively, you can give B an init which doesn't call its super class, thus instantiating it without calling A's init. I don't particularly recommend this method:
class A():
def __init__(self):
print('A class')
def name(self):
print('name from A class')
class B(A):
def __init__(self):
print('B class')
def b_name(self):
print('b_name from B class')
self.name()
B().b_name()
> B class
> b_name from B class
> name from A class

How do I access instance data from a method in python?

So I am trying to create a public method that can be called by class a so that it edits a data item in class b.
class aClass():
def __init__(self):
aVariable = 1
class aNotherClass():
def aMethod(self):
aFunction(5)
def aFunction(aNumber):
instance1.aVariable = aNumber
instance1 = aClass()
instance2 = aNotherClass()
instance2.aMethod
However, when I call instance1 in aFunction, python tells me it isn't defined. If I want to change aVariable in aClass, what should aFunction() say?
I think you may forget the self when you define a class method.
refer to: https://docs.python.org/2/tutorial/classes.html#class-objects
class aClass():
def __init__(self):
aVariable = 1
class aNotherClass():
def aMethod(self):
aFunction(5)
def aFunction(aNumber):
instance1.aVariable = aNumber
instance1 = aClass()
instance2 = aNotherClass()
instance2.aMethod()

Categories