class A(object):
def __init__(self):
self.a = 1
class B(A):
def __init__(self):
A.__init__(self)
self.a = 2
self.b = 3
class C(object):
def __init__(self):
self.a = 4
self.c = 5
class D(C, B):
def __init__(self):
C.__init__(self)
B.__init__(self)
self.d = 6
obj = D()
print(obj.a)
My understanding is that python will first search class C then B then A to get a. So print(obj.a) will print out 4 when searching class C. But the answer is 2. This means that Python got self.a = 2 from class B instead of self.a = 4 from class C. Can anyone explain the reasons? Thank you
There is no search going on here. You are making explicit, direct calls to unbound methods, passing in self manually. These are simple function calls, nothing more.
So this is just a question of tracing the execution order:
D() -> D.__init__(self)
C.__init__(self)
self.a = 4
B.__init__(self)
A.__init__(self)
self.a = 1
self.a = 2
So a is assigned 4, then 1, then 2.
Related
I have this--
class A(object):
def __init__(self):
self.b = 1
self.c = 2
self.d = 4
I want --
class A(object):
def __init__(self):
self.b = 1
self.c = 2
self.d = 4
def do_nothing(self):
a={'b':1,'c':2,'d':4}
how to use instance variable as key value in another r method
Magic methods __dict__ can help you
class A(object):
def __init__(self):
self.a = 1
self.b = 2
self.c = 3
def test(self):
print(self.__dict__)
a = A()
a.test()
Output
{'a': 1, 'b': 2, 'c': 3}
Imagine I have:
class ABC():
def main(self, x):
self.x = x
class A(ABC):
def afunction(self):
self.a = 2
class B(ABC):
def bfunction(self):
self.b = self.a * self.x
return self.b
How is it possible that class B inherits the self.a and self.x from class A and ABC? (I do not care about inheriting the methods)
If I understand correctly, what you want is to get B to inherit from A.
Notice that what will happen is that it will inherit A variables, and because A inherits from ABC, B will inherit ABC's variables as well.
Also, please note that you will have to initialize the x variable for example inside an B object in order to use the bFunction, and in general it is proper coding to set a constructor as follows:
class ABC():
def __init__(self, x=0):
self.x = x
def main(self, x):
self.x = x
class A(ABC):
def __init__(self, a=2):
super().__init__()
self.a = a
def afunction(self):
self.a = 2
class B(A):
def __init__(self, b=0):
super().__init__()
self.b = b
def bfunction(self):
self.b = self.a * self.x
return self.b
b = B()
b.main(3)
b.afunction()
print(b.bfunction())
Output:
6
If B inherits from A, which inherits from ABC, then B will have ABC and A's methods but neither the 'x' or 'a' attributes which are only set after the methods are run. This works if you rewrite B as:
class B(A):
def bfunction(self, x):
self.main(x)
self.afunction()
self.b = self.a * self.x
return self.b
b = B()
print(b.bfunction(10))
You have to supply 'x' to b.bfunction so that self.b = self.a * self.x works.
Getting below Attribute error while running below code. Class member function is accessed using self still it is giving error.
class A:
def __init__(self):
self.a=1
def f1(self):
self.b=2
def f2(self):
self.c=3
print(self.a,self.b,self.c)
self.f2()
model = A()
model.f1()
Error:
AttributeError: 'A' object has no attribute 'f2'
A does not have an attribute f2, but it does have an attribute f1 that calls a function f2. f2 is not an instance attribute.
In this case c is no longer an instance attribute, or data attribute, it is now just a local variable. This may or may not be what you were
going for.
class D:
def __init__(self):
self.a = 1
def f1(self):
# Instance attribute declared outside of __init__
self.b = 2
def f2():
c = 3
print(self.a, self.b, c)
f2()
Depending on your development environment you may or may not get a warning about instance attributes being declare outside of the __init__ function. It isn't necessary that you declare them this way, however, it improves readability.
class B:
def __init__(self):
self.a = 1
self.b = 2
self.c = 3
def f1(self):
def f2():
print(self.a, self.b, self.c)
f2()
This next block is slightly more explicit in what it says about the intent of the code.
class A:
def __init__(self):
self.a = 1
self.b = 2
self.c = 3
def f1(self):
def f2():
return '{} {} {}'.format(self.a, self.b, self.c)
return f2()
Perhaps you want f2() to be called using method attributes of the
self argument in which case:
class A2:
def __init__(self):
self.a = 1
self.b = 2
self.c = 3
def f2(self):
print(self.a, self.b, self.c)
def f1(self):
"""Do something that requires calling the self.f2()
print function.
"""
self.f2()
You do not need self when calling the nested function and nor does it need to be contained in the function signature:
class A:
def __init__(self):
self.a=1
def f1(self):
self.b=2
def f2():
c=3
print(self.a,self.b, c)
f2()
model = A()
model.f1()
Output:
1, 2, 3
Its not clear to me that you actually need to define a function within a method just to call it.
So, your code could just as easily be this:
class A:
def __init__(self):
self.a = 1
def f1(self):
self.b = 2
self.f2()
def f2(self):
self.c = 3
print(self.a, self.b, self.c)
model = A()
model.f1()
Output:
1 2 3
Given a parent class 'A'
class A(object):
def __init__(self,a,b):
self.a = a
self.b = b
def methodA():
# do something
What is the difference between making a subclass 'B' among the below options
Option 1
class B(A):
def methodB():
# do something
Option 2
class B(A):
def __init__(self,a,b):
A.__init__(self, a, b)
def methodB():
# do something
class A(object):
def __init__(self,a,b):
self.a = a
self.b = b
class B(A):
def __init__(self,a,b):
A.__init__(self, a, b)
def methodB():
pass
class C(A):
def methodB():
pass
b = B(1,2)
c = C(1,2)
print b.a == c.a # True
print b.b == c.b # True
In both class instantiation, init under class A will be ran only once.
so no, there is nothing significantly different.
class B is not clean IMO and poses no real purpose at all. It will be ran anyways.
If you wish to do something different in class B init, then yes, you can use this code.
class B(A):
def __init__(self,a,b):
A.__init__(self, a+1, b+1)
def methodB():
pass
I have two classes:
class A(object):
def __init__(self, b):
self b = b
class B(object):
def __init__(self, a):
self a = a
I'd like to init them like this:
a = A(b)
b = B(a)
But I can't since 'b' doesn't exist when doing a = A(b). I have to do:
a = A()
b = B(a)
b.a = a
But that seems unclean. Is this solvable?
You could either make one class instantiate the other:
class A(object):
def __init__(self):
self.b = B(self)
class B(object):
def __init__(self, a):
self.a = a
a = A()
b = a.b
Or make one class tell the other about itself, like this:
class A(object):
def __init__(self, b):
self.b = b
b.a = self
class B(object):
def __init__(self):
#Will be set by A later
self.a = None
b = B()
a = A(b)