Reputation: 5044
An API I use defines a method like this:
def show_prop(object, propname): #...
What it's supposed to do is display the property on screen by calling getattr(object, propname)
and allow the user to change the attribute, resulting in setattr(object, propname)
.
There is no way I can change that behaviour but I want to use the API to show a local variable to the user and receive the normal feedback from the user?
I thought of a builting variable describing the current scope and the variables available, kind of like a local __dict__
but I haven't found such thing.
userinput = "Default input"
show_prop(__mysterious_unknown__, 'userinput')
# Do something exciting with the changed userinput
Is this possible to achieve?
Upvotes: 1
Views: 318
Reputation: 114529
No. Local write access can be done only directly in the scope or in nested scopes using nonlocal
(Python3 only).
Python doesn't have the concept of "pointer" and the only way to specify a writable place is passing a reference to the container and the "name" of the member (or the index of the array, the key of the dict).
What you can do is however create a small object on the fly just for this:
class Bunch:
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
def foo():
my_local = 42
...
myobj = Bunch(my_local=my_local) # create the dummy instance
show_prop(myobj, "my_local") # call the original code
my_local = myobj.my_local # get modified value back
...
In Python3 would be possible to create a magic object instance that when written to the member will mutate the local on the fly (using the new Python3 nonlocal
keyword and either a property or a __getattr__
/__setattr__
catch-all). I wouldn't go for this kind of strange magic unless it's really needed however...
For example:
def foo(obj, name):
# the fixed API
setattr(obj, name, 1 + getattr(obj, name))
def bar():
myloc = 11
# magic class...
class MyClass:
def __getattr__(self, name):
# accessing any member returns the current value of the local
return myloc
def __setattr__(self, name, value):
# writing any member will mutate the local (requires Python3)
nonlocal myloc
myloc = value
foo(MyClass(), "myloc")
print(myloc) # here myloc will have been incremented
bar()
Upvotes: 1