I would like to implement a widget system similar to FLTK using python in a 3D world.
I simplified my code to the following. I don't get the correct answer. The function is not overwritten even if I change the variable.
def callbacks():
print("callback")
def create():
print ("override")
def default():
print("default")
class f1(object):
def __init__(self):
self.test=default
pass
def docallback(self):
self.test()
class f2(f1):
def __init__(self):
self.test=create
super().__init__()
class f3(f2):
def __init__(self):
self.test=callbacks
super().__init__()
t1=f1()
t2=f2()
t3=f3()
t1.docallback()
t2.docallback()
t3.docallback()
You should be calling super().__init__() first in this case:
class f1(object):
def __init__(self):
self.test = default
def docallback(self):
self.test()
class f2(f1):
def __init__(self):
super().__init__()
self.test = create
class f3(f2):
def __init__(self):
super().__init__()
self.test = callbacks
These 'constructors' call super().__init__() first (which makes assignments to self.test), but then immediately assigns the correct value to self.test itself.
f1.__init__ should use default as the default value of a parameter, not a hard-coded assignment.
class f1:
def __init__(self, test=default):
self.test = test
Then f2 and f3 can simply provide different arguments when using super().
class f2:
def __init__(self):
super().__init__(create)
class f3:
def __init__(self):
super().__init__(callbacks)
Related
I have a question about accessing a variable between two classes, where one is the base class. I have a program which I'm writing where there's a single 'settings' variable and it's shared between several classes. This is a simplistic version of it.
This code snippet works. When I run it, I can access run() from the Top class, and both classes have access to self.settings, and when I print it out from go(), it contains both 'a' and 'b' keys.
The problem is, pylint and my IDE say "Instance of 'Base' has no 'settings' member". Which I understand is because it's not initialized in Base.init().
class Base:
def __init__(self):
self.settings["b"] = False
def run(self):
print("RUN")
class Top(Base):
def __init__(self):
self.settings = dict(a=True)
Base.__init__(self)
def go(self):
print(self.settings)
x = Top()
x.go()
x.run()
This is a slightly modified version, where I am passing 'self' from Top twice to Base, and using 'main.settings' instead of self.settings. Pylint nor my IDE complain about this. I'm clearly passing the self instance into it to share, so I understand that.
class Base:
def __init__(self, main):
main.settings["b"] = False
def run(self):
print("RUN")
class Top(Base):
def __init__(self):
self.settings = dict(a=True)
Base.__init__(self, self)
def go(self):
print(self.settings)
x = Top()
x.go()
x.run()
What I don't understand, is what is the proper way to achieve this? The other option of course is to pass the settings variable itself. However I have several variables and possibly methods which need to be used by both classes, so passing 'self' seems like the best option.
Init settings in Base, not Top.
class Base:
def __init__(self):
self.settings = {}
self.settings["b"] = False
def run(self):
print("RUN")
class Top(Base):
def __init__(self):
Base.__init__(self)
self.settings["a"] = True
def go(self):
print(self.settings)
Child classes should depend on their parent classes, not vice versa. If Base doesn't init self.settings, then it depends on some other as-yet-undefined class to init it (which is a bad dependency/assumption to introduce).
You should create self.settings in the base class, not the child. Then the child can add its key to it after calling the base's __init__() method.
class Base:
def __init__(self):
self.settings = {"b": False}
def run(self):
print("RUN")
class Top(Base):
def __init__(self):
super().__init__()
self.settings['a'] = True
def go(self):
print(self.settings)
x = Top()
x.go()
x.run()
I would pass in **kwargs, so it's easy to keep insertion order the same as you had it:
class Base:
def __init__(self, **kwargs):
self.settings = {**kwargs, 'b': False}
def run(self):
print("RUN")
class Top(Base):
def __init__(self):
super().__init__(a=True)
def go(self):
print(self.settings)
x = Top()
x.go()
x.run()
Output:
{'a': True, 'b': False}
RUN
I am trying to call an instance variable from a "parent" class (subclass) to it's "child" class (subsubclass)
class mainclass():
def __init__(self):
self.mainclassvar1 = "mainclass"
class subclass(mainclass):
def __init__(self):
self.subclassvar1 = "subclass"
def changeval(self):
self.subclassvar1 = "subclassedited"
class subsubclass(subclass):
def __init__(self):
self.subsubclassvar1 = subclass.subclassvar1 #<- naturally this fails
def handler():
main=mainclass()
sub = subclass()
sub.changeval()
subsub = subsubclass()
print(subsub.subsubclassvar1)# <- how do I achieve this? I would expect "subclassedited" but it doesn't
if __name__ == "__main__":
handler()
The above does not work obviously but I am trying to show what I am trying to achieve in my head.
if I change the class subsubclass(subclass) as follows it semi-works:
class subsubclass(subclass):
def __init__(self):
subclass.__init__(self)
self.subsubclassvar1 = self.subclassvar1
however the returned value is the original default value of subclass instead of the expected subclassedited.
I am not sure if I should even be trying to do this but I've got some code where the logic has now come to this point and I want to try see if I can get details from the middle class in to the final child class in their final modified states instead of the defaults and without refactoring a lot of code.
Each __init__ method should be invoking the parent's __init__ method, so that the instance is properly initialized for all the classes in the hierarchy.
class mainclass:
def __init__(self):
super().__init__()
self.mainclassvar1 = "mainclass"
class subclass(mainclass):
def __init__(self):
super().__init__()
self.subclassvar1 = "subclass"
def changeval(self):
self.subclassvar1 = "subclassedited"
class subsubclass(subclass):
def __init__(self):
super().__init__()
# Not sure why you would really need this, but...
self.subsubclassvar1 = self.subclassvar1
There's no reason, though that subsub.subclassvar1 should be related to sub.subclassvar1, though. Calling sub.changeval() has nothing to do with subsub.
I want to use a variable from class A for some computation in class B. I,m not sure that I use the self.out from the class A in class B appropriately?
Class A:
class A(nn.Module):
def __init__(self):
super(A, self).__init__()
self.out = func()
Class B:
class B(nn.Module):
def __init__(self):
super(A, self).__init__()
self.result = function_1() + A.self.out
Maybe this is what you need. I made a small example of what I understood.
These "prints" were placed to improve the understanding that Class "C" can fetch any function or variable from the other parent classes.
class A():
def __init__(self):
variable = None
def test(self, number):
return f'another class {number}'
class B():
def __init__(self):
self.data = None
self.out = self.print_data(5)
def print_data(self, number):
return number
def print_elem(self):
return self.data
class C(A, B):
def __init__(self):
super().__init__()
c = C()
print(c.print_data(8))
print(c.out)
c.data = 100
print(c.print_elem())
print(c.test(3))
class A:
def __init__(self):
pass
#staticmethod
def a():
return "a"
class B1(A):
def __init__(self):
super().__init__()
#staticmethod
def a():
return "b"
class B2(A):
def __init__(self):
super().__init__()
class C1(B1):
def __init__(self):
super().__init__()
#staticmethod
def a():
return super(C1, C1).a()
class C2(B1):
def __init__(self):
super().__init__()
#staticmethod
def a():
return super(B1, B1).a()
So here's a tricky thing I'm having understanding.
B2().a() returns a, even though B2 doesn't have a method called a().
How come?
Also, I don't quite understand how staticmethod differs from the other methods.
Every class here inherits (directly or indirectly) from A (that's what class B2(A): is telling you).
Since they inherit from A, they have access to A's methods. All the #staticmethod decorator does is suppress passing self to the method implicitly when it's called on an instance, so that A.a() and A().a() work the same; similarly, B2.a() and B2().a() work the same way, invoking A.a().
I have a class scheme with 2-levels of inheritance. My expectation is that each class constructor would run through- and yet the mid-level class constructor never seems to get hit. What's missing here?
class Base(object):
def __init__(self):
print "BASE"
class Next(Base):
def __init__(self):
super(Base, self).__init__()
print "NEXT"
class Final(Next):
def __init__(self):
super(Next, self).__init__()
print "FINAL"
f = Final()
Outputs:
BASE
FINAL
Why does "NEXT" not print??
You should be calling super() with the current class, not the parent.
class Base(object):
def __init__(self):
super(Base, self).__init__()
print "BASE"
class Next(Base):
def __init__(self):
super(Next, self).__init__()
print "NEXT"
class Final(Next):
def __init__(self):
super(Final, self).__init__()
print "FINAL"
f = Final()
At first glance this might seem redundant ("why can't it just get the class from self?") - but keep in mind that the same self is passed to all three of these __init__ methods when f is created, and that self is always of class Final. Thus, you have to pass super() the class that you want it to find the parent of.
class Base(object):
def __init__(self):
print "BASE"
class Next(Base):
def __init__(self):
super(Next, self).__init__()
print "NEXT"
class Final(Next):
def __init__(self):
super(Final, self).__init__()
print "FINAL"
f = Final()