Getting the parent of a dynamically method as a function
@Phuket2, you can give getattr a value to be used if the attribute does not exist.
You again have an interesting problem at hand, although I am not sure what you need this for.
I looked at the ui module, and it does have code to instantiate ui objects from the JSON provided by the ui editor. Now if @omz just had some code in his back pocket to generate matching JSON from ui instances, your copy thing would be done, and we would have a method for serializing ui components. Still not sure what we need it for, though.
@mikael , yes I understand you can get define a default return for querying a attr. But it just needs more than what I have done at the moment. Need to know the type of what is expected, which is not that difficult. But requires even more knowledge of what attr you are dealing with. For example you can see that the attr requires a tuple. Well that's wide open.
But you mention why I/we need it. Imagine in the ui.designer you couldn't copy and paste elements. In my mind it's the same thing. In the ui.designer you can also copy and paste attributes. Why should we not have this in code? I just think we should have.
Look I know I have some strange ideas. But in all honesty, I can't see why in a perfect world I can't just copy a object in full and or its attributes as you would in a gui. Especially if the copy is done very low level. Then I change a few attrs of the very fast memory copied object.
Just my 2 cents worth.
@Phuket2, crazy ideas push the envelope and occasionally advance the state of the art, so I am all for them. And I can understand the analogy to UI designer.
Copying plain Python objects is just that easy, but unfortunately these ones have an ObjectC monster behind the friendly facade. And copying UIKit instances even in ObjectC is not totally trivial, see this link.
Fixed a simple bug, now self.methods can be called in
import types class Extender(object): def __new__(extender_subclass, target_instance, *args, **kwargs): extender_instance = super(Extender, extender_subclass).__new__(extender_subclass) for key in dir(extender_instance): if key.startswith('__'): continue value = getattr(extender_instance, key) if callable(value): setattr(target_instance, key, types.MethodType(value.__func__, target_instance)) else: setattr(target_instance, key, value) if isinstance(extender_subclass.__init__, types.MethodType): extender_subclass.__init__.__func__(target_instance, *args, **kwargs) return target_instance
@mikael , i am struggling to get my head around your extender concept. I don't mean the way you have written it. Just a bit fancy for me 😱
If I want to add a new class to chain it so to speak, how would I do that? I tried a few things but failed.
@Phuket2, here's a quick, silly and familiar-looking example demonstrating both the subclass inheritance chain and chaining extenders around a button instance. If this is of no use, please share some problematic code.
import ui from extend import Extender class DefaultStyle(Extender): background_color = 'teal' tint_color = 'white' class BorderedStyle(DefaultStyle): border_width = .5 corner_radius = 3 class ButtonAction(Extender): def __init__(self, msg = None): self.msg = msg def action(self, sender): print self.msg button = BorderedStyle(ButtonAction(ui.Button(title = 'Click me'), 'Clicked')) button.present()
Phuket2 last edited by Phuket2
@mikael , ok. You mentioned chained before. These are nested Calls right? I am not being smart, I am just not sure of the terminology used in this context.
But even is not that practical, I would hate to nest say 5 calls
@Phuket2, I see what you mean. This version does not chain as much as it nests, that's true. Let me see if I can do something about that.
Here's one way to chain, specifically, if you do not mind "polluting" your ui components with an extra method, named
ehere for brevity.
# coding: utf-8 import ui from extend import Extender class ChainingExtender(Extender): def e(self, cls, *args, **kwargs): return cls(self, *args, **kwargs) class DefaultStyle(ChainingExtender): background_color = 'teal' tint_color = 'white' class BorderedStyle(DefaultStyle): def __init__(self, border_width): self.border_width = border_width self.border_color = 'white' class ButtonAction(ChainingExtender): def __init__(self, new_title = 'Not defined'): self.msg = new_title def action(self, sender): self.title = self.msg button = ButtonAction(ui.Button(title = 'Click me'), 'Clicked').e(BorderedStyle, 10) button.present()
@mikael , 0k I will have to look tomorrow. 1:47am here now 😱 With many black label and sodas 🎉
But I hope you don't mind, my idea is to keep pushing your idea until it breaks. When it can not be broken, not just by me , but then it should be great.