On Tue, 15 Nov 2005 03:23:11 -0600, Chris Mellon <[EMAIL PROTECTED]> wrote:
>On 11/14/05, Bengt Richter <[EMAIL PROTECTED]> wrote: [...] >> You may be interested in reviewing >> >> http://groups.google.com/group/comp.lang.python/browse_thread/thread/= >f96b496b6ef14e2/32d3539e928986b3 >> >> before continuing this topic ;-) > >I read that thread, and am glad I did before asking like I was going >to, if only to avoid being yelled at for not understanding Python >variables ;) > >I understand them, I really do, and I know why they act the way they >do, but I still wanted a reference type for binding GUI objects to >data values - for example, a spinner control to an int value. In C++, >I do it by passing a pointer to an int to the control and letting it >do its thing. Theres no simple obvious way to do the same thing in >Python - I ended up by passing a namespace(any object) and an >attribute (by name) and then setting it via setattr in in the control, >which is non-obvious and icky. > ISTM that there are two main issues involved. 1) Can you code your intentions with some clean syntax? 1a) Is there clean syntax to help you think more fluently? 2) Is the implementation efficient enough for your use case? (Ok, I couldn't help introducing 1a, because I think that is where Python shines). I think 2) can be ignored until we have a good proposal for 1) ;-) IIUC what you want boils down to wanting to replace a value via a reference object that you pass to a function, where the value is known by name in some namespace, and you don't want to use a (namespace, namestring) tuple as a reference object. Actually, in general the value could be known by some access expression that doesn't necessarily end in a name, like a[42]. Our magic ref expression (let's use function syntax for now for creating the reference) becomes more tricky. We now also have ref(a[42]) as well as ref(name). For easy discussion of the concept, let's assume that refobj = ref(expr) works for some subset of exprs and refobj lets us access the expr target via refobj.value for assignment or in an expression. Note that the name 'value' is not the name in ref(name), but is always 'value'. We can discuss later whether we want syntactic sugar to spell refobj.value as @refobj or maybe even plain refobj, but let's postpone that until we have agreed functionality and some ideas on implementation. So, to summarize, we have refobj = ref(expr) and we can assign to the indirect target and and use it in an expression refobj.value = refobj.value + 1 with a fixed syntax that does not identify any of the original expression (since "value" is an arbitrarily chosen mnemonic and attribute access is an arbitrarily chosen accessor mechanism for discussion expediency). For your example of ref(namespace.name) we could use my PNS class [1] to get a refobj that acts as above, e.g., >>> from pns import PNS >>> namespace = type('NS',(),{})() # an object providing attr namespace >>> refobj = PNS(namespace, 'name') >>> refobj.value = 'should wind up in namespace' >>> namespace.name 'should wind up in namespace' >>> refobj.value 'should wind up in namespace' >>> [1] http://groups.google.com/group/comp.lang.python/msg/54a7ab01906683ca But how would ref(a[42]) work? By analogy we might have a class PLE (pointer to list element) and instantiate it by refobj = PLE(a, 42). That would be easy. One could even imagine a multimethod __init__ for a PXX class that would handle a number of common ref(expr) situations, if you pass the appropriate pieces of expr as args. One could imagine automating this in various ways. E.g., treating ref as a keyword and automatically detecting it in a module's AST and translating the call to pick apart the passed expression suitably to make a call that generates the refobj. But this is premature implementation ;-) Let's get the requirements down first. One thing that pops up immediately if you think about ref(namespace.name) vs ref(a[42]) is preservation of the dynamic access semantics whose execution is deferred in time. I.e., a dangling pointer problem with additional twists. If the essential ref infos are (namespace, name) and (a, 42), we must note that we really implicitly made it (namespace, ('__getattr__', '__setattr__', '__delattr__'), name) and (a, ('__getitem__', '__setitem__', '__delitem__'), 42) (at least I did in the way I defined PNS, because deferred use of the refobj to set a value implied doing getattr(namespace, name) at that time. Accessor methods could also be bound at ref call time, with different semantics resulting. I.e., we could have ref info stored as ((namespace.__getattr__, namespace.__setattr__, namespace.__delattr__), name) and ((a.__getitem__, a.__setitem__, a.__delitem__), 42) What is the real meaning desired for a refobj ? How should ref(42) be handled? Should it become a legal refobj that only fails if used as assignment target, so that it can be passed transparently to read-only users as well as references to mutables that wind up only being used read-only? Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list