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
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
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
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
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
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()