omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    __init_subclass__ Just asking (py 3.6)

    Pythonista
    subclassing
    4
    10
    3776
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Phuket2
      Phuket2 last edited by Phuket2

      @omz, I understand ui Elements are done in Objective-C and can't be sub classed. But does the introduction of the init_subclass hook in py3.6 give any new opportunities? I am guessing the answer is no, but wanted to ask anyway.

      1 Reply Last reply Reply Quote 0
      • dgelessus
        dgelessus last edited by

        When you define an __init_subclass__ method on a class, that method is called when you subclass that class. This only really helps you when you are writing the base class, which isn't the case here.

        The reason why the ui.View subclasses can't be subclassed is different. It's not that classes implemented in C cannot be subclassed - after all, object and ui.View are also implemented in C, and you can subclass those. The issue is that (as I understand it) C classes do not support subclassing by default, and if you want to support it, you need to add extra custom handling for each class. There are quite a lot of default ui.View subclasses, so omz might have decided that it's not worth the effort to write and test subclassing support for each one.

        Phuket2 1 Reply Last reply Reply Quote 1
        • Phuket2
          Phuket2 @dgelessus last edited by

          @dgelessus , thanks for the good explanation. I am wondering if I got the right magic method here. I was watching a video about 3.6 changes and they mentioned a magic method that you get called on before the init is called. Basically so you can avoid having to do the tricks to craft a class before it's built.
          I have to go back and watch the video. It sounded important and interesting. I was initially thinking that it might have been a help to the stuff @jonb did with bindings to get a loaded pyui file into custom class.
          Anyway, I will rewatch the video and see

          1 Reply Last reply Reply Quote 0
          • omz
            omz last edited by

            @dgelessus is right. The reason ui.View subclasses (and some other things) cannot be subclassed further is that supporting subclassing requires additional precautions. It's not that it's impossible (see ui.View), but it's more work than simply not allowing subclassing (e.g. ui.Rect).

            Phuket2 1 Reply Last reply Reply Quote 0
            • Phuket2
              Phuket2 @omz last edited by

              @omz , ok. Fair enough. But has come a long way. Can add attrs at runtime, can pass all **kwargs for creation. The bindings also helped with pyui classes. So just saying many enhancements have been made to supplement not being able to subclass thinks like ui.Button.

              The below example has always frustrated me. That is if you add a method to a ui Element at runtime, you cant get a reference to the instance of the object calling the method. Maybe there is a way I don't know about. But as far as I know you cant.

              I am looking from the point of view, if these items cant be subclassed, what do you really need from subclassing the item. The one I mention here would be a good one to have as I see it.

              import ui
              
              def pos(sender=None, x=0, y=0):
              	print('hello, but i dont which object called me')
              	print(f'btw x={x} and y={y}')
              	'''
              		i would like it possible that sender was valid here.
              		i dont want to have to pass in the reference to the object as a param
              	'''
              	
              if __name__ == '__main__':
              	btn = ui.Button(frame = (20, 20, 80, 32),
              							bg_color='white',
              							border_width =.5)
              	btn.title = 'Hit Me'
              	btn.present(style='sheet')
              	btn.pos = pos
              	btn.pos(None, 10, 20)
              
              1 Reply Last reply Reply Quote 0
              • JonB
                JonB last edited by JonB

                __new__ gets called before init, maybe that is what you were thinking?

                BTW, what you are trying can be accomplished using MethodType --binding an instance method to an instance.

                Adapted from stackoverflow:

                import types
                
                def patch_me(target):
                    def pos(self,x,y):
                        print ("x=",x,"y=",y)
                        print ("called from", self)
                    target.pos = types.MethodType(pos,target)
                    #add more if needed
                import ui
                
                a = ui.Button()
                print (a)
                patch_me(a)    #patch instance
                a.pos(10,20)
                

                Using this approach, hopefully it should be obvious that you can sort of "subclass" ui.Button, though only sort of (the button still thinks it is a ui.Button, and you cannot override existing methods).

                You could probably do this in a more generic way, say you define a custom class, which takes a Button in __new__, which then traverses over instance methods in your NewClass and binds them to your button instance, then calls your NewClass.__init__ on the button, and finally returns the now patched button.

                Phuket2 1 Reply Last reply Reply Quote 0
                • Phuket2
                  Phuket2 @JonB last edited by

                  @JonB, thanks again. I remember code around like this before. Not sure it was exactly the same of not.
                  But I could not get this example working. I sort of can see what is happening. I get the trace back as listed below.

                  I played around with this statement target.method = types.MethodType(method,target) , but could not figure out how to get it correct.

                  Did you run it also?

                  Traceback (most recent call last):
                  File "/private/var/mobile/Containers/Shared/AppGroup/3533032E-E336-4C25-BBC4-112A6BF2AF75/Pythonista3/Documents/MyProjects/scratch/patching_ui_methods.py", line 13, in <module>
                  patch_me(a) #patch instance
                  File "/private/var/mobile/Containers/Shared/AppGroup/3533032E-E336-4C25-BBC4-112A6BF2AF75/Pythonista3/Documents/MyProjects/scratch/patching_ui_methods.py", line 7, in patch_me
                  target.method = types.MethodType(method,target)
                  NameError: name 'method' is not defined

                  1 Reply Last reply Reply Quote 0
                  • JonB
                    JonB last edited by

                    sorry, i edited it in real time to make it specifc to your pos method, but then forgot the generic one. I fixed the code above. method should have been pos

                    Phuket2 2 Replies Last reply Reply Quote 0
                    • Phuket2
                      Phuket2 @JonB last edited by

                      @JonB , thanks a lot. Sorry, I couldn't work it out. I was close, but still a million miles away. I never remember it being this easy to do this. I remembered I wanted to call positioning code on the ui.object rather than passing the object into functions. Also other things. But this is a nice addition to have. I didn't re watch that video yet, but i will. When i was watching it, the first thing that went though my mind is that it may simplify the pyui wrapper class you made. Although there is nothing wrong with it, still works fine.

                      Ok, but thanks again.

                      1 Reply Last reply Reply Quote 0
                      • Phuket2
                        Phuket2 @JonB last edited by

                        @JonB, I found this Talk from PyCon 2017. Know thy self, methods and method-bindings. I haven't had time to watch it all yet, but pretty sure this will help me understand all this a bit better.
                        I also mention for others who might read this thread.

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post
                        Powered by NodeBB Forums | Contributors