Nate, I find this mightily interesting! I think it's worth discussing at length.
Is there any chance you'll want to move the discussion to the richer context here? https://discuss.python.org/c/ideas Regards, On Tue, Jun 25, 2019 at 5:00 PM nate lust <natel...@linux.com> wrote: > This message is related to two previous threads, but was a sufficiently > evolved to warrant a new topic. > > I am proposing that two new magic methods be added to python that will > control assignment and loading of class > instances. This means that if an instance is bound to a variable name, any > attempts to rebind that name will > result in a call to the __setself__ (name negotiable) of the instance > already bound to that name. Likewise > when a class instance bound to a name is loaded by the interpreter, if > present, the __getself__ method of that > instance will be called and its result will be returned instead. I have > been internally calling these cloaking > variables as they "cloak" the underlying instance, parallelling the idea > of shadowing. Feel free to suggest > better names. > > > On first read, that may be surprising, but it extends a behavior pattern > that already exists for things like > properties (and generically descriptors) to object instances themselves. > Similar caveats and behaviors will > apply here as well. > > A working implementation built against python 3.7 can be found here: > https://github.com/natelust/cpython/tree/cloakingVars. This is not pull > ready quality code, but the diffs may > be interesting to read. > > An example for what is possible for this new behavior are instance level > properties as seen in the demo at the > end of this message. > > These changes have minimal impact on the runtime of existing code, and > require no modifications to existing > syntax other than the use of the names __setself__ and __getself__. > > A more detailed write-up with more examples can be found at > https://github.com/natelust/CloakingVarWriteup/blob/master/writeup.md, > with the example executable demo here: > https://github.com/natelust/CloakingVarWriteup/blob/master/examples.py > > The demos include: > * Variables which keep track of their assignment history, with ability to > rollback (possibly useful with try > except blocks) > * Variables which write out their value to disk when assigned to > * An implementation of context variables using only this new framework > (does not implement tokens, but could > be added) > * const variables that can be used to protect module level 'constants' > * Instance properties (reproduced below) that allow dynamically adding > properties > * An implementation of templated expression, to defer the addition of many > arrays to a single for loop, > saving possibly expensive python iterations. > > I am sure the community can come up with many more interesting ideas. > > class InstanceProperty: > > def __init__(self, wrapped, getter, setter=None): > self.wrapped = wrapped > self.getter = getter > self.setter = setter > > def __getself__(self): > return self.getter(self.wrapped) > > def __setself__(self, value): > if self.setter: > return self.setter(self.wrapped, value) > > > class MachineState: > def __init__(self): > self._fields = {} > > def add_input(self, name, start): > def getter(slf): > return slf._fields[name] > > def setter(slf, value): > ''' > the state of a machine part can only be above zero or below > 100 > ''' > if value < 0: > value = 0 > if value > 100: > value = 100 > slf._fields[name] = value > setter(self, start) > inst_prop = InstanceProperty(self, getter, setter) # noqa: F841 > # Need to directly assign the instance property, or decloak it. > setattr(self, name, getcloaked('inst_prop')) > > > machine = MachineState() > > for letter, start in zip(['a', 'b', 'c'], [-1, 0, 1]): > machine.add_input(letter, start) > > print(f"machine.a is {machine.a}") > print(f"machine.b is {machine.b}") > print(f"machine.c is {machine.c}") > > # Assign a value that is too high > machine.c = 200 > > print(f"machine.c is {machine.c}") > # Omited from this proposal but present in the linked documentation are > # tools for getting the underlying variables, and or rebinding them. > > On Fri, Jun 21, 2019 at 9:34 PM nate lust <natel...@linux.com> wrote: > >> It probably doesn't, this was just something I typed up on the fly, so is >> unlikely the end result would be what you see above if it was actually >> implemented. >> >> The only way around that that I can think of now would be if there was >> two functions, an impl_dictget that actually did the lookup that type could >> use (and possibly getattr and the like) which would be called in the normal >> dict get which would just return if the type did not define __getself__ and >> would call it and return the result if it did. >> >> This is not at all dissimilar to how dict setting works now >> >> On Fri, Jun 21, 2019, 9:27 PM Chris Angelico <ros...@gmail.com> wrote: >> >>> On Sat, Jun 22, 2019 at 11:19 AM nate lust <natel...@linux.com> wrote: >>> > Typing this out though does make me think of an interesting idea. If >>> there was something like __getself__ in addition to __setself__, you could >>> implement things like MyInt. __getself__ would look something like: >>> > >>> > class MyInt: >>> > def __init__(self, value): >>> > self.value = value >>> > def __getself__(self): >>> > return self.value >>> > def __setself__(self, value): >>> > raise ValueError("Cant set MyInt") >>> > x = MyInt(2) >>> > print(x) -> 2 >>> > type(x) -> MyInt >>> > >>> > Now I have not really thought through how this would work, if it could >>> work... >>> >>> How does print know to call getself, but type know not to? >>> >>> ChrisA >>> _______________________________________________ >>> Python-ideas mailing list -- python-ideas@python.org >>> To unsubscribe send an email to python-ideas-le...@python.org >>> https://mail.python.org/mailman3/lists/python-ideas.python.org/ >>> Message archived at >>> https://mail.python.org/archives/list/python-ideas@python.org/message/3734V62OHMJN3736PKWQ7IZ533TPM23J/ >>> Code of Conduct: http://python.org/psf/codeofconduct/ >>> >> > > -- > Nate Lust, PhD. > Astrophysics Dept. > Princeton University > _______________________________________________ > Python-ideas mailing list -- python-ideas@python.org > To unsubscribe send an email to python-ideas-le...@python.org > https://mail.python.org/mailman3/lists/python-ideas.python.org/ > Message archived at > https://mail.python.org/archives/list/python-ideas@python.org/message/TMU3MJCDVNAHMJQAJUBIHRJXXLYMWSRH/ > Code of Conduct: http://python.org/psf/codeofconduct/ > -- Juancarlo *Añez*
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/IFLFKZDDFMX4O5PD2YKPZ6OPB372MWZP/ Code of Conduct: http://python.org/psf/codeofconduct/